com.sun.messaging.mq
imqxm
4.6-b01
javaee
javaee-api
5
xalan
xalan
2.7.0
com.sun.messaging.mq
jaxm-api
4.6-b01
JMS message sender (Embedded SoapMessage with Attachment)
import com.google.common.io.Files;
import com.sun.messaging.xml.MessageTransformer;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.xml.soap.*;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Hashtable;
public class MockWebServiceOverJMSSender {
private static final String CONNECTION_FACTORY_JNDI_NAME = "weblogic.jms.XAConnectionFactory";
private static final String QUEUE_JNDI_NAME = "jms/TestQueueJNDI";
public static void sendMessage() {
try {
QueueConnection connection = null;
QueueSession session = null;
QueueSender queueSender = null;
try {
Hashtable<String,String> properties = new Hashtable();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
properties.put(Context.PROVIDER_URL, "t3://localhost:7001");
InitialContext context = new InitialContext(properties);
QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup(CONNECTION_FACTORY_JNDI_NAME);
connection = connectionFactory.createQueueConnection();
session = connection.createQueueSession(false, 0);
Queue queue = (Queue) context.lookup(QUEUE_JNDI_NAME);
queueSender = session.createSender(queue);
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
soapMessage.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPBody soapBody = envelope.getBody();
soapBody.setTextContent(buildSoapBodyContent());
AttachmentPart attachment = buildSoapAttachment(soapMessage);
soapMessage.addAttachmentPart(attachment);
soapMessage.saveChanges();
Message message = MessageTransformer.SOAPMessageIntoJMSMessage(soapMessage, session);
queueSender.send(message);
} finally {
queueSender.close();
session.close();
connection.close();
}
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
private static String buildSoapBodyContent() throws IOException {
String responseFile = "c:/temp/PoliceAVOApplicationResponse-Non-provisional.xml";
return Files.toString(new File(responseFile), Charset.forName("UTF-8"));
}
private static AttachmentPart buildSoapAttachment(SOAPMessage soapMessage) {
DataHandler dh = new DataHandler(new FileDataSource("c:/temp/test_avo.pdf"));
return soapMessage.createAttachmentPart(dh);
}
public static void main(String args[]) {
sendMessage();
}
JMS consumer(parse message body & save attachment to disk)
import au.gov.nsw.police.nodi.common.IOHelper;
import com.google.common.io.Files;
import com.sun.messaging.xml.MessageTransformer;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.*;
import javax.xml.xpath.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
public class MockJMSMessageConsumer {
private static final String CONNECTION_FACTORY_JNDI_NAME = "weblogic.jms.XAConnectionFactory";
private static final String QUEUE_JNDI_NAME = "jms/TestQueueJNDI";
private static void consumeMessage() {
try {
QueueConnection connection = null;
QueueSession session = null;
QueueReceiver queueReceiver = null;
try {
Hashtable<String, String> properties = new Hashtable();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
properties.put(Context.PROVIDER_URL, "t3://localhost:7001");
InitialContext context = new InitialContext(properties);
QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup(CONNECTION_FACTORY_JNDI_NAME);
connection = connectionFactory.createQueueConnection();
session = connection.createQueueSession(false, 0);
Queue queue = (Queue) context.lookup(QUEUE_JNDI_NAME);
queueReceiver = session.createReceiver(queue);
connection.start();
while (true) {
Message message = queueReceiver.receive(1);
MessageFactory messageFactory = MessageFactory.newInstance();
if (message != null) {
SOAPMessage soapMessage = MessageTransformer.SOAPMessageFromJMSMessage(message, messageFactory);
onMessage(soapMessage);
}
}
} finally {
queueReceiver.close();
session.close();
connection.close();
}
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(0);
}
}
private static void onMessage(SOAPMessage soapMessage) {
try {
System.out.println("Start to processing message from ESB...");
SOAPBody soapBody = soapMessage.getSOAPPart().getEnvelope().getBody();
Iterator iterator = soapMessage.getAttachments();
if (iterator.hasNext()) {
AttachmentPart attachmentPart = (AttachmentPart) iterator.next();
System.out.println("here");
parseMetadataFromSoapMessage(soapBody, attachmentPart);
}
System.out.println("Finish to processing message from ESB");
} catch (Throwable e) {
e.printStackTrace();
}
}
private static void parseMetadataFromSoapMessage(SOAPBody soapBody, AttachmentPart attachmentPart) throws IOException, SAXException, ParserConfigurationException, XPathExpressionException, SOAPException {
String content = soapBody.getTextContent();
Document doc = buildDocumentFromString(content);
XPath xPath = createXPath();
String courtReferenceNumber = getStringValueWithGiveXPath(xPath, doc, "/n1:PublishDocumentMessage/@ProceedingNumber");
String courtName = getStringValueWithGiveXPath(xPath, doc, "/n1:PublishDocumentMessage/n1:Listing/Court/@Name");
String eventNumber = getStringValueWithGiveXPath(xPath, doc, "/n1:PublishDocumentMessage/n1:QuestionsAndAnswers/n1:DataField[@Name='IDF POLAPPEVENTNO']/@Value");
String cni = getStringValueWithGiveXPath(xPath, doc, "/n1:PublishDocumentMessage/n1:Participant[n1:ParticipantID[@ParticipantRole='DEFENDANT']]/n1:CrimeIndividual/common:IndividualDetails/@CNI");
System.out.println("court reference number: " + courtReferenceNumber);
System.out.println("court name: " + courtName);
System.out.println("event number: " + eventNumber);
System.out.println("cni: " + cni);
saveAttachmentToDisk(attachmentPart);
}
private static Document buildDocumentFromString(String content) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
InputStream inputStream = new ByteArrayInputStream(content.getBytes());
return docBuilder.parse(inputStream);
}
private static XPath createXPath() {
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
xpath.setNamespaceContext(new AVONamespaceContext());
return xpath;
}
private static String getStringValueWithGiveXPath(XPath xpath, Document document, String expression) throws XPathExpressionException {
XPathExpression xPathExpression = xpath.compile(expression);
return (String) xPathExpression.evaluate(document, XPathConstants.STRING);
}
private static void saveAttachmentToDisk(AttachmentPart attachmentPart) throws IOException, SOAPException {
byte[] pdfFile= IOHelper.readInputStream(attachmentPart.getDataHandler().getInputStream());
Date now = new Date();
Files.write(faxImages, new File("c:/temp/" + now.getTime() + ".pdf"));
}
public static void main(String args[]) {
consumeMessage();
}
help class
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import java.util.Iterator;
public class AVONamespaceContext implements NamespaceContext {
public String getNamespaceURI(String prefix) {
if (prefix == null) throw new NullPointerException("Invalid Namespace Prefix");
else if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
return "http://www.w3.org/2001/XMLSchema-instance";
} else if ("n1".equals(prefix)) {
return "http://cats.agd.nsw.gov.au/PublishDocumentMessage/v1_0";
} else if ("common".equals(prefix)) {
return "http://cats.agd.nsw.gov.au/DocumentLodgementInterfaces/Common/v1_0";
} else if ("cim".equals(prefix)) {
return "http://cim.justicesector.nsw.gov.au/Common/1";
} else if ("as4590".equals(prefix)) {
return "http://cim.justicesector.nsw.gov.au/as459";
} else {
return XMLConstants.NULL_NS_URI;
}
}
public String getPrefix(String namespaceURI) {
return null;
}
public Iterator getPrefixes(String namespaceURI) {
return null;
}
}
Another Solution
You don't need to dependent the above dependencies. You just implement your own transformer. My sample as follow:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.xml.messaging.JAXMException;
import javax.xml.soap.*;
import java.io.*;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import static com.google.common.base.Throwables.getStackTraceAsString;
/**
* The Rcode>Transformer</code> class encapsulates the functionality
* to transform SOAP and JMS messages.
*/
public class MessageTransformer {
private static final Logger log = LoggerFactory.getLogger(MessageTransformer.class);
private MessageTransformer() {
}
/**
* Transforms a <code>javax.xml.soap.SOAPMessage</code> message
* into a <code>javax.jms.Message</code> message.
*
* @param soapMessage the SOAPMessage to be converted to the JMS Message.
* @param session The JMS Session to be used to construct the JMS Message.
* @throws JAXMException If any error is encountered when transforming the message.
*/
public static Message SOAPMessageIntoJMSMessage(SOAPMessage soapMessage, Session session) throws JAXMException {
try {
/**
* Construct a bytes message object.
* This is to make sure the utility works across all vendors.
*/
BytesMessage bytesMessage = session.createBytesMessage();
/**
* This is here to make sure that RI's bad SOAP implementation
* will get updated for internal buffers.
*/
soapMessage.saveChanges();
writeMimeHeaders(soapMessage, bytesMessage);
writeSOAPBody(soapMessage, bytesMessage);
return bytesMessage;
} catch (JAXMException JAXMe) {
throw JAXMe;
} catch (Exception e) {
log.error(getStackTraceAsString(e));
throw new JAXMException(e);
}
}
private static void writeMimeHeaders(SOAPMessage soapMessage, BytesMessage bytesMessage) throws Exception {
MimeHeaders mimeHeaders = soapMessage.getMimeHeaders();
Hashtable hashtable = convertMimeHeadersToHashtable(mimeHeaders);
ByteArrayOutputStream mimeOut = writeHashtableToByteArrayOutputStream(hashtable);
byte[] mimeHeadersBytes = mimeOut.toByteArray();
int mimeHeadersLength = mimeHeadersBytes.length;
bytesMessage.writeInt(mimeHeadersLength);
bytesMessage.writeBytes(mimeHeadersBytes);
mimeOut.close();
log.debug("SOAP to JMS mime headers length: {}", mimeHeadersLength);
}
/**
* Convert MimeHeaders to Hashtable. The hashtable is then used to write
* to JMS BytesMessage.
*/
private static Hashtable convertMimeHeadersToHashtable(MimeHeaders mimeHeaders) {
Hashtable hashtable = new Hashtable();
Iterator it = mimeHeaders.getAllHeaders();
while (it.hasNext()) {
MimeHeader mimeHeader = (MimeHeader) it.next();
hashtable.put(mimeHeader.getName(), mimeHeader.getValue());
}
return hashtable;
}
private static ByteArrayOutputStream writeHashtableToByteArrayOutputStream(Hashtable hashtable) throws IOException {
ByteArrayOutputStream mimeOut = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(mimeOut);
objectOutputStream.writeObject(hashtable);
objectOutputStream.flush();
objectOutputStream.close();
return mimeOut;
}
private static void writeSOAPBody(SOAPMessage soapMessage, BytesMessage bytesMessage) throws Exception {
ByteArrayOutputStream bodyOutput = new ByteArrayOutputStream();
soapMessage.writeTo(bodyOutput);
byte[] bodyBytes = bodyOutput.toByteArray();
int bodyLength = bodyBytes.length;
bytesMessage.writeInt(bodyLength);
bytesMessage.writeBytes(bodyBytes);
bodyOutput.close();
log.debug("SOAP to JMS body length: {}", bodyLength);
}
/**
* Extracts a <code>javax.xml.soap.SOAPMessage</code> object from the
* <code>javax.jms.Message</code> object into which it was transformed
* using the <code>SOAPMessageIntoJMSMessage</code> method.
* <p/>* The <code>MessageFactory</code> parameter is used to construct the
* <code>javax.xml.soap.SOAPMessage</code> object.
* <p/>* If <code>MessageFactory</code> is <code>null</code> then the
* default SOAP MessageFactory will be used to construct the
* SOAP message.
*
* @param message The JMS message from which the SOAP message is to be extracted.
* @param messageFactory The SOAP MessageFactory to be used to contruct the SOAP message.
* @throws JAXMException If any error is encountered when extracting the message.
*/
public static SOAPMessage extractSOAPMessageFromJMSMessage(Message message, MessageFactory messageFactory) throws JAXMException {
BytesMessage bytesMessage = (BytesMessage) message;
try {
MimeHeaders mimeHeaders = readMimeHeaders(bytesMessage);
ByteArrayInputStream bodyByteArrayInputStream = readSoapBodyToByteArrayInputStream(bytesMessage);
return constructSoapMessage(messageFactory, mimeHeaders, bodyByteArrayInputStream);
} catch (Exception e) {
throw new JAXMException(e);
}
}
private static MimeHeaders readMimeHeaders(BytesMessage bytesMessage) throws JMSException, IOException, ClassNotFoundException {
int mimeHeadersLength = bytesMessage.readInt();
byte[] mimeHeadersBytes = new byte[mimeHeadersLength];
bytesMessage.readBytes(mimeHeadersBytes, mimeHeadersLength);
ByteArrayInputStream mimeHeadersByteArrayInputStream = new ByteArrayInputStream(mimeHeadersBytes);
ObjectInputStream objectInputStream = new ObjectInputStream(mimeHeadersByteArrayInputStream);
Hashtable hashtable = (Hashtable) objectInputStream.readObject();
return convertHashtableToMimeHeaders(hashtable);
}
private static MimeHeaders convertHashtableToMimeHeaders(Hashtable hashtable) {
MimeHeaders mimeHeaders = new MimeHeaders();
Enumeration enm = hashtable.keys();
while (enm.hasMoreElements()) {
Object key = enm.nextElement();
mimeHeaders.addHeader((String) key, (String) hashtable.get(key));
log.debug("mime-header: {} = {}", key, hashtable.get(key));
}
return mimeHeaders;
}
private static ByteArrayInputStream readSoapBodyToByteArrayInputStream(BytesMessage bytesMessage) throws JMSException {
int bodyLength = bytesMessage.readInt();
byte[] buf = new byte[bodyLength];
bytesMessage.readBytes(buf, bodyLength);
return new ByteArrayInputStream(buf);
}
private static SOAPMessage constructSoapMessage(MessageFactory messageFactory, MimeHeaders mimeHeaders,
ByteArrayInputStream bodyByteArrayInputStream) throws SOAPException, IOException {
if (messageFactory == null) {
messageFactory = getMessageFactory();
}
return messageFactory.createMessage(mimeHeaders, bodyByteArrayInputStream);
}
private static MessageFactory getMessageFactory() throws SOAPException {
return MessageFactory.newInstance();
}
}
reference
SOAP over Java Message Service 1.0
No comments:
Post a Comment