JAXM不是j2ee1.4的标准规范。saaj和jax-rpc只能同步通信,jaxm 支持异步。可以使用代理,还有Messaging profiles 。
从JAVA Web service1-3例举的主要是sun支持的技术,你选择第三方的包,asix,ebxml, 其他实现。jax-rpc在1。5的实现更为简单,对开发来说。这里只是提供一些参考,和他们之间的结构和区别。
Profile string | Description |
---|---|
Returns a MessageFactory that can be used to create messages with preconfigured headers as defined by the SOAP WS-Routing protocol. WS-Routing (which stands for Web Services Routing) was formerly known as the SOAP Routing Protocol, or SOAP-RP (hence the name of the profile — we'll refer to it throughout this chapter as SOAP-RP or soaprp for consistency with the implementation). It allows the route by which a SOAP message reaches its ultimate destination to be recorded in the message header, and for a suitable reverse path to be created as the message is forwarded through intermediary systems. Section 4.5, later in this chapter, looks at the support for this profile in the JAXM reference implementation. | |
Returns a MessageFactory for messages with headers that conform to the ebXML Message Service specification. See Section 4.6, later in this chapter, for further information on this profile. |
jaxm的三种传输模式:
下面是ebxml profile例子:
web.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">
<web-app> <display-name>SOAP-RP Echo Service</display-name> <description>SOAP-RP Echo Service</description> <servlet> <servlet-name>SOAPRPEcho</servlet-name> <display-name>Servlet for the SOAP-RP Message Echo Service</display-name> <servlet-class>ora.jwsnut.chapter4.soaprpecho.SOAPRPEchoServlet</servlet-class> <load-on-startup>1000</load-on-startup> </servlet> <servlet-mapping> <servlet-name>SOAPRPEcho</servlet-name> <url-pattern>/message</url-pattern> </servlet-mapping> </web-app>
client.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE ClientConfig PUBLIC "-//Sun Microsystems, Inc.//DTD JAXM Client//EN" "http://java.sun.com/xml/dtds/jaxm_client_1_0.dtd"> <ClientConfig> <Endpoint> urn:SOAPRPEcho </Endpoint> <CallbackURL> http://localhost:8080/SOAPRPEcho/message </CallbackURL>
<Provider> <URI>http://java.sun.com/xml/jaxm/provider</URI> <URL>http://localhost:@port@/jaxm-provider/sender</URL> </Provider> </ClientConfig>
例子请看
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); } } }
package ora.jwsnut.chapter4.soaprpsender;
import java.io.IOException; import java.io.OutputStream; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; 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.messaging.ProviderMetaData; import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPFactory; import javax.xml.soap.SOAPMessage; import com.sun.xml.messaging.jaxm.soaprp.SOAPRPMessageFactoryImpl; import com.sun.xml.messaging.jaxm.soaprp.SOAPRPMessageImpl;
/** * A servlet that creates a SOAP-RP message on demand and sends * it to a remote echo service. */ public class SOAPRPSenderServlet extends JAXMServlet implements OnewayListener { /** * Message returned by the echo service. */ private SOAPMessage replyMessage; /** * Factory used to create parts of SOAP messages */ private SOAPFactory soapFactory; /** * ProviderConnection used to send reply messages */ private ProviderConnection conn; /** * Factory used to create messages */ private MessageFactory msgFactory; /** * Initialize by installing the appropriate MessageFactory */ public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); try { // Create the connection to the provider conn = ProviderConnectionFactory.newInstance().createConnection(); soapFactory = SOAPFactory.newInstance(); // Check that the soaprp profile is supported ProviderMetaData metaData = conn.getMetaData(); String[] profiles = metaData.getSupportedProfiles(); boolean found = false; for (int i = 0; i < profiles.length; i++) { if (profiles[i].equals("soaprp")) { found = true; break; } } if (!found) { // No SOAPRP profile log("soaprp profile not supported"); throw new ServletException("soaprp profile not supported"); } // Get the message factory and build the message msgFactory = conn.createMessageFactory("soaprp"); // Install the factory to use when receiving messages setMessageFactory(msgFactory); } catch (Exception e) { e.printStackTrace(); throw new ServletException( "Failed to initialize SOAPRP sender servlet " + e.getMessage()); } } /** * Handles a request from a client to send a message. */ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // Only allow gets on the "request" handler String path = req.getServletPath(); if (!path.equals("/request")) { resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Cannot use get on this URL"); return; } // Build and send a message boolean sent = sendMessage(); // Wait until the echo service has replied, // for a maximum of 30 seconds if (sent) { synchronized (this) { replyMessage = null; try { if (replyMessage == null) { wait(30000L); } } catch (InterruptedException ex) { } } } // Now send the reply to the caller. try { if (replyMessage == null) { resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "No reply received"); return; }
OutputStream os = resp.getOutputStream(); resp.setContentType("text/html"); resp.setStatus(HttpServletResponse.SC_OK); os.write("<html><P><XMP>".getBytes()); replyMessage.writeTo(os); os.write("</XMP></html>".getBytes()); os.flush(); } catch (Exception ex) { log("Exception in doGet", ex); resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "Exception: " + ex.getMessage()); } replyMessage = null; } /** * Handles a POST either from a client or as a * callback from the provider. */ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { // Only allow posts to the "message" handler String path = req.getServletPath(); if (path.equals("/message")) { // This is allowed super.doPost(req, resp); } else { // Cannot post to the request path resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Cannot post to this URL"); } } /* -- Useful functionality starts here -- */ /** * Builds a message and sends it to the service */ private boolean sendMessage() { try { // Build the SOAP-RP essage SOAPRPMessageImpl message = (SOAPRPMessageImpl)msgFactory.createMessage(); message.setTo(new Endpoint("urn:SOAPRPEcho")); message.setFrom(new Endpoint("urn:SOAPRPSender")); SOAPElement element = message.getSOAPPart().getEnvelope().getBody().addBodyElement( soapFactory.createName("Sent", "tns", "urn:SOAPRPSender")); element.addTextNode("This is the content"); // Send the message to the echo service conn.send(message); // Return indicating that the message was sent. return true; } catch (Exception ex) { log("Failed when sending message", ex); } return false; } /** * Handles a received SOAP message - this is the * asynchronous reply from the echo service. */ public void onMessage(SOAPMessage message) { try { synchronized (this) { // Save the message for the benefit // of the client. replyMessage = message;
// Wake up the client notify(); } } catch (Exception ex) { log("Exception", ex); } } }
两个简单的例子大概的说明一下。以上的内容都是引用自Java Web Services in a Nutshell.chm
可以通过我的资源中得到,不过是E文。