package ora.jwsnut.chapter4.soaprpecho;
import java.util.Date;
import java.util.Iterator;
import java.util.Vector;
import java.io.ByteArrayOutputStream;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.xml.messaging.Endpoint;
import javax.xml.messaging.JAXMServlet;
import javax.xml.messaging.OnewayListener;
import javax.xml.messaging.ProviderConnection;
import javax.xml.messaging.ProviderConnectionFactory;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPMessage;
import com.sun.xml.messaging.jaxm.soaprp.SOAPRPMessageImpl;
/**
* A servlet that recieves a SOAP-RP messages and
* returns it to its sender.
*/
public class SOAPRPEchoServlet extends JAXMServlet implements OnewayListener {
/**
* Output stream used to save a SOAP message
* for logging.
*/
private ByteArrayOutputStream os = new ByteArrayOutputStream();
/**
* ProviderConnection used to send reply messages
*/
private ProviderConnection conn;
/**
* Initialize by installing the appropriate MessageFactory
*/
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
// Workaround for hang when deploying in J2EE container.
// Do not connect to the provider here - defer to another thread.
new Thread(new Runnable() {
public void run() {
try {
// Create the connection to the provider
conn = ProviderConnectionFactory.newInstance().createConnection();
// Work around for a JAXM bug
conn.getMetaData();
// Install the message factory for the SOAP-RP profile
setMessageFactory(conn.createMessageFactory("soaprp"));
} catch (Exception e) {
log("Exception when initializing", e);
}
}
}).start();
}
/**
* Handles a received SOAP message
*/
public void onMessage(SOAPMessage message) {
// Convert the message to string representation
// and log it.
try {
message.writeTo(os);
log("Received SOAP message:\n" + os.toString());
os.reset();
// Create a copy of the message with the same body
// and with the to and from addresses exchanged.
SOAPRPMessageImpl soapMsg = (SOAPRPMessageImpl)message;
MessageFactory factory = soapMsg.getMessageFactory();
// Create a reply message
SOAPRPMessageImpl replyMsg = (SOAPRPMessageImpl)factory.createMessage();
// Move the body content from the received message to the source.
SOAPBody body = soapMsg.getSOAPPart().getEnvelope().getBody();
SOAPBody replyBody = replyMsg.getSOAPPart().getEnvelope().getBody();
Iterator iter = body.getChildElements();
while (iter.hasNext()) {
SOAPElement element = (SOAPElement)iter.next();
replyBody.addChildElement(element);
}
// Add an element after the body that contains the date.
SOAPElement element =
replyMsg.getSOAPPart().getEnvelope().addChildElement("Date", "tns", "urn:SOAPRPEcho");
element.addTextNode(new Date().toString());
// Copy any attachments
iter = soapMsg.getAttachments();
while (iter.hasNext()) {
replyMsg.addAttachmentPart((AttachmentPart)iter.next());
}
// Get the SOAP message ID and install it as the "relates-to" value
replyMsg.setRelatesTo(soapMsg.getSOAPRPMessageId());
// Get the the "To" address and install it as the "From" address
replyMsg.setFrom(soapMsg.getTo());
// Get the "From" address an install it as the "To" address
replyMsg.setTo(soapMsg.getFrom());
// Copy the "action"
replyMsg.setAction(soapMsg.getSOAPRPAction());
// Install the reverse path, if there is one, as the forward path
Vector revPath = soapMsg.getSOAPRPRevMessagePath();
int count = revPath.size();
for (int i = 0; i < count; i++) {
replyMsg.updateFwdMessagePath((Endpoint)revPath.get(i), i);
}
// Send the reply message
conn.send(replyMsg);
} catch (Exception ex) {
log("Exception", ex);
}
}
} |