1. Trang chủ
  2. » Công Nghệ Thông Tin

Xml programming bible phần 9 potx

99 326 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 99
Dung lượng 1,65 MB

Nội dung

752 Part VII ✦ Web Services and J2EE Figure 33-3: SOAP message with attachments Messages that are exchanged between client and server can be exchanged in syn- chronous and asynchronous modes. In reality, there are a few variations on these two modes. The complete list of message exchange modes is as follows: ✦ Asynchronous Inquire: A message is sent and a response must be received (not immediately, but at some point in the future) ✦ Asynchronous Update with Acknowledgement: A message is sent and a spe- cific acknowledgement must be received ✦ Synchronous Update: A message is sent and the sender blocks until a response is received ✦ Synchronous Inquiry: This is the same as Synchronous Update; however, the response is only needed to unblock the client ✦ Fire and Forget: A message is sent and no response is expected or received Connections All messages that are exchanged via JAXM are sent and received via connections. A connection simply represents any link between a client (a sender) and its corre- sponding service (a receiver). Based on the type of client you are developing, you Header Body Attachment 1 Attachment 2 Attachment Envelope SOAP Part SOAP Message o538292 ch33.qxd 8/18/03 8:45 AM Page 752 753 Chapter 33 ✦ Web Services with the Sun Java Web Services Developer Pack may choose to connect directly to a service or you may connect to a message provider, which will route your message to its ultimate destination. Each connection is created using the typical factory pattern. For example, if you wanted to create a direct connection to a service, referred to as a point-to-point connection, you would simply invoke the static SOAPConnectionFactory. newInstance() method, which would return a SOAPConnection object. You could then use that connection for all of your synchronous interactions with the service. For asynchronous messaging, you would create a ProviderConnection by invoking the ProviderConnectionFactory.newInstance() method. The interfaces for both of these models are very straightforward. JAXM package structure When JAXM was initially introduced, all of it classes and interfaces were contained in the javax.xml.messaging package. This made perfect sense until JAXM inher- ited its dependency on SAAJ. Since SAAJ really offers a set of API that can (and do) exist outside the JAXM domain, it no longer made sense to package it alongside JAXM. So, to clarify this point and eliminate some unnatural coupling, the elements of SAAJ were broken out of the JAXM package and made part of the javax.xml. soap package. JAXM still retains its dependency on the javax.xml.soap pack- age (as it should), but javax.xml.soap has no dependency on javax.xml. messaging. This move also freed up the SOAP APIs so it could be more cleanly referenced by other APIs, most notably the JAX-RPC API. The items shown in Table 33-1 represent some of the key classes and interfaces that appear in these two packages. Table 33-1 Axis Package Contents javax.xml.messaging javax.xml.soap ProviderConnectionFactory SOAPConnectionFactory ProviderConnection SOAPConnection ProviderMetaData SOAPEnvelope ReqRespListener SOAPHeader OneWayListener SOAPBody EndPoint AttachmentPart JAXMException SOAPFault o538292 ch33.qxd 8/18/03 8:45 AM Page 753 754 Part VII ✦ Web Services and J2EE Profiles Out of the box, JAXM supports the SOAP 1.1 and SOAP with attachments specifica- tions. However, the JAXM architecture also allows the SOAP model to be extended to support additional protocols via profiles. These profiles call out additional mes- saging specifications, which allow messages to conform to any number of new pro- tocol requirements. So, messages received with a given profile will contain specific header attributes that are part of the agreed upon protocol for that profile’s specifi- cation. Each profile will be accompanied by an API that will support the processing and manipulation of these custom header attributes. In the case of JAXM, APIs are included for both ebXML and SOAP-RP profiles. As Web Services gain wider acceptance, we may also see the introduction of new, more industry-specific profiles. JAXM’s ability to support these profiles so seam- lessly will put it in a good position to accommodate these continually evolving specifications. JAXM versus JMS At this point, you may be wondering where JAXM fits into the grand messaging scheme with JMS. It’s true that at some abstract level all of these technologies rep- resent alternative approaches to messaging. They all seek to provide a reliable framework for routing and receiving messages. However, even though they share this higher-level objective, they are still different enough in their execution that they shouldn’t be seen as being interchangeable. JMS and JavaMail implementations typically rely on some incarnation of Messaging Oriented Middleware (MOM) or mail infrastructure to transport and manage their messages. This is still a perfectly valid model for some problem domains. In fact, it may be the preferred solution in more controlled development environments (where both the sending and receiving technology is more under your control). JAXM is not making any attempt to be a superset of all these message solutions. Instead, it is focused specifically on being a Web-centric messaging solution, embracing the Web Service vision of SOAP flowing freely across a multitude of applications and programming environments. Certainly, given the level of standard- ization being achieved with the SOAP protocol, JAXM will have clear advantages in terms of its ability to interoperate with a broad range of technologies. The JAXM technology does offer a few options that are not available with JMS. In general, JAXM is viewed as a lighter-weight solution than JMS. Its support for syn- chronous, point-to-point connections is also not available to JMS developers. These features, although marginally important, are worth mentioning. o538292 ch33.qxd 8/18/03 8:45 AM Page 754 755 Chapter 33 ✦ Web Services with the Sun Java Web Services Developer Pack Building a client Now that we’ve covered the fundamental concepts behind JAXM, let’s put them to work by building some sample clients. Fortunately, with JAXM (and most messaging APIs), there are very few gory details buried within the API. In fact, as we move through this example, it should become evident that the JAXM learning curve is fairly minimal. The steps involved in building our examples, and most JAXM clients, will typically follow the same basic pattern. ✦ Create a connection from one of JAXM’s connection factories ✦ Construct a message ✦ Populate the content of the message ✦ Add attachments (if you have any) to the message ✦ Send the message ✦ Receive a response ✦ Extract the content from the received message Building a standalone client Standalone clients are the simplest to build, so let’s start there. As we mentioned before, a standalone client does not use a message provider and is constrained to synchronous communications. In this example, we’ll just send a simple message directly to a service and receive a response. The first step involved in building our client is to acquire a connection to the service from a connection factory. The code to get our connection is shown in Listing 33-1. Listing 33-1: Getting a Connection SOAPConnectionFactory connFactory = SOAPConnectionFactory.newInstance(); SOAPConnection conn = connFactory.createConnection(); Whew, that was hard. Our connection object is ready, now we need to construct the message we want to send to the service. As we saw earlier in our discussion of JAXM packages, the javax.xml.soap contains all the classes and interfaces we’ll need to build a SOAP message that we can exchange with a service. In our example, we’ll send messages to the Cosmic Astrology service, which will take some simple demographic data points and return a horoscope. The message will be constructed with the code shown in Listing 33-2. o538292 ch33.qxd 8/18/03 8:45 AM Page 755 756 Part VII ✦ Web Services and J2EE Listing 33-2: Constructing a Message // get the SOAP elements MessageFactory msgFactory = MessageFactory.newInstance(); SOAPMessage msg = msgFactory.createMessage(); SOAPPart soapPart = msg.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); SOAPHeader header = envelope.getHeader(); SOAPBody body = envelope.getBody(); header.detachNode(); // create a name for our service entry point Name methodName = envelope.createName(“GetHoroscope”, “ASTRO”, “http://www.astro.com”); SOAPBodyElement getHoroscope = body.addBodyElement(methodName); // add parameter birth date Name dobParamName = envelope.createName(“DateOfBirth”); SOAPElement dobParam = getHoroscope.addChildElement(dobParamName); dobParam.addTextNode(“05/03/1964”); // add parameter for favorite color Name colorParamName = envelope.createName(“FavoriteColor”); SOAPElement colorParam = getHoroscope.addChildElement(colorParamName); colorParam.addTextNode(“Purple”); This code starts out by getting a message from the MessageFactory. We can then use this message to pull out all the separate elements of the SOAP message (SOAPEnvelope, SOAPHeader, and SOAPBody), which will then be used to assem- ble our service call. In this particular example, we won’t need to have any header information and, since header information is optional in SOAP message, we’ll use the detach() method on SOAPHeader to remove the header portion of our message. Next, we need to create a Name object that represents the entry point for the opera- tion (GetHoroscope) we want to call on our service. This is achieved by creating a Name object with the method name (GetHoroscope), namespace (ASTRO), and URI (http://www.astro.com). Our constructed Name is then added as a body ele- ment to the message body. To round out our message, we need only add the parameters that will be passed with our call. In this sample, we’ll pass DateOfBirth and FavoriteColor param- eters to our service. Again, we’ll construct these parameters as Name instances before adding each one as a child element to the getHoroscope body element that we have already created. o538292 ch33.qxd 8/18/03 8:45 AM Page 756 757 Chapter 33 ✦ Web Services with the Sun Java Web Services Developer Pack Now, when JAXM sends this message, it will transform it into a valid SOAP message with each of the data elements we added mapped to the appropriate part of the message. In this example, the SOAP message shown in Listing 33-3 would be produced. Listing 33-3: The SOAP Message <SOAP-ENV:Envelope xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/” <SOAP-ENV:Body> <ASTRO:GetHoroscope xmlns:ASTRO=”http://www.astro.com”> <DateOfBirth>05/03/1964</DateOfBirth> <FavoriteColor>Purple</FavoriteColor> </ASTRO:GetHoroscope> </SOAP-ENV:Body> </SOAP-ENV:Envelope> There’s only one thing left for us to do— send the message and get our response. This achieved by constructing an EndPoint and invoking the call() on our con- nection. Once the call is completed, a SOAPResponse will be returned with your horoscope. The code for making this call is shown in Listing 33-4. Listing 33-4: Making the Call SOAPMessage response = conn.call(msg, endPoint); conn.close(); System.out.println(“Received reply”); SOAPPart soapRespPart = response.getSOAPPart(); SOAPEnvelope soapRespEnv = soapRespPart.getEnvelope(); SOAPBody soapRespBody = soapRespEnv.getBody(); Iterator it = soapRespBody.getChildElements(); SOAPBodyElement bodyElement = (SOAPBodyElement)it.next(); String horoscope = bodyElement.getValue(); System.out.println(“Horoscope returned: “ + horoscope); Alas, we have our horoscope. Now, to get the text of our horoscope, we extract the SOAPBodyElement from response and display its value. As a matter of housekeep- ing, we also close the connection to free up the resource. o538292 ch33.qxd 8/18/03 8:45 AM Page 757 758 Part VII ✦ Web Services and J2EE Clients with message providers Building a client that uses a message provider follows much of this same logic as our standalone client, but it requires a few extra pieces of information to handle messages. Let’s look at some the nuances that differentiate the clients that leverage message providers. When clients wish to use a message provider, they have two options for acquiring their connection. They can use the ProviderConnectionFactory. newInstance() mechanism, which will return the default provider. The other approach would be to use the Java Naming and Directory Interface (JNDI) to look up a provider based on its name. The following code provides an example of how this would be executed. Context jndiContext = new InitialContext(); ProviderConnectionFactory provFactory = (ProviderConnectionFactory)jndiContext.lookup(“RegisteredProvider1”); ProviderConnection provConn = provFactory.createConnection(); JAXM also provides a number of different options for constructing messages that will be routed through a message provider. With a message provider, we may choose to use a message format that conforms to one of the available message pro- files (remember, profiles let us include data in the SOAP header that allows a mes- sage to comply with a given message specification). If we’re planning on using a message that uses one of these profiles, we’ll need to get a special message factory type for that profile. This factory is acquired as follows: MessageFactory ebXMLFactory = provConn.createMessageFactory(“ebxml”); EbXMLMessageImpl ebXMLMessage = (EbXMLMessageImpl)ebxmlFactory.createMessage(); In this example, we created a message factory that references the ebXML profile and then uses this factory to create a message. You’ll notice that the value returned from our createMessage() call must be cast to an instance of an EbXMLMessageImpl. Now, with the instance of an EbXMLMessageImpl, we can use this classes’ type-safe interface to set the ebXML compliant header values. Each provider connection actually maintains a list of all the profiles it supports as part of its metadata. The following line of code will return an array of strings that represent the collection of profiles that are supported for the provConn connection instance: String[] profiles = provConn.getMetaData().getSupportedProfiles(); Naturally, each profile comes with its own set of requirements that will influence how you’ll go about populating your message. It’s outside the scope of this book to explore the message requirements for each of these profiles. That last step is to send the message, which is also slightly different for clients that use message providers. Instead of using the call() method, the Provider o538292 ch33.qxd 8/18/03 8:45 AM Page 758 759 Chapter 33 ✦ Web Services with the Sun Java Web Services Developer Pack Connection uses send() to initiate the message exchange. The send() message takes a single parameter, the populated message. You’ll notice that with send() we were not required to include an endpoint. With message providers, the endpoints are actually included as part of the deployed configuration for that message provider, allowing the provider to assume reponsibility for assigning the ultimate destination for your message. It’s also important to note that the send() method does not require a response. Once the method is called, control is immediately returned to the caller. Handling a SOAPFault In the JAXM world, error conditions cannot be raised as exceptions. The only data that passes between sender and receiver is SOAP messages. So, instead of employ- ing your usual handy try/catch block, you’ll need to peek into SOAP reponses to see if they include a SOAPFault object. This object defines a standard “exception-like” interface for setting and retrieving information about a given error condition. The following snippet of code demonstrates the detection and display of a SOAPFault condition: SOAPMessage response = conn.call(messsage, endPointURL); SOAPBody respBody = response.getSOPAPart().getEnvelope().getBody(); if (respBody.hasFault() == true) { SOAPFault fault = respBody.getFault(); System.err.println(“Fault Code: “ + fault.getFaultCode() + “Fault Text: “ + fault.getFaultString()); } The SOAP 1.1 specification actually calls out each of the attributes of the SOAPFault and how they must be populated. If you plan on throwing your own SOAPFault objects, you’ll want to look more closely at this area of the specification. The Provider Admin tool The JWSDP includes a utility that is used to manage your message provider configu- rations. This Web-based application includes tools for adding and editing end- points, configuring log file options, message retry intervals, and so on. Once you’ve got Tomcat up and running, you can access this tool by selecting the “Provider Administration” link on the http://localhost:8080/index.html page. Java API for XML-Based RPC (JAX-RPC) In the preceding discussion of JAXM, our emphasis was on broadcasting and receiv- ing SOAP messages. In fact, it should be clear by now that JAXM and SOAP are heavily intertwined. Nearly every line of JAXM code you will write will require some o538292 ch33.qxd 8/18/03 8:45 AM Page 759 760 Part VII ✦ Web Services and J2EE awareness of the SOAP API. In stark contrast, the JAX-RPC API has the expressed goal of completely isolating developers from SOAP. How a message is delivered and how its results are returned should be of little concern to the JAX-RPC developer. Each JAX-RPC implementation should be measured, to some extent at least, on how well it executes on this vision. Ideally, building or consuming a Web Service with JAX-RPC should be as simple as it would be with any other traditional distributed model. Part of what makes the JAX-RPC learning curve so minimal is the fact that much of its approach borrows directly from the existing RMI and RPC models. Developers who have experience with these technologies should find the transition to JAX-RPC especially smooth. If we allow some room for over-simplification, in fact, it would probably be safe to think of JAX-RPC as RMI that swaps out the RMI transport layer and plugs in standard HTTP and SOAP 1.1 compliant message exchange. If we look at the diagram shown in Figure 33-4, we’ll see that JAX-RPC clients leverage generated stubs that then pass off controls to a JAX-RPC run-time layer that takes on the responsibility for dealing with all the serialization and SOAP message formatting that’s needed to send our call to a Web Service. On the service side, as you might expect, the JAX-RPC plumbing listens for incoming service calls, de-serializes the SOAP messages into Java types, and ends up calling a method on our service. Now, even though the JAX-RPC API isn’t exactly revolutionary, what it enables for developers is still significant. With JAX-RPC, developers will be able to build and consume Web Services relatively easily. And, with SOAP as its underlying protocol, it opens up a whole new level of interoperability. With a few simple steps, our clients can reach out across the Web and interact with a broad range of services developed with any number of different Web Service compliant tools and technolo- gies. We can also build and deploy our Java classes as Web Services with very little extra plumbing added to our every day Java classes. All this talk of the simplicity of JAX-RPC might lead one to overlook its power. Even though JAX-RPC implementations limit ramp-up time, they also offer a fairly rich set of more advanced features. The specification calls out mechanisms for mapping user-defined types, custom message handler chains, embedding documents in your messages, and so on. The type-mapping system should be of particular interest, since you’re likely to need to exchange additional data types in your service inter- faces. We’ll touch on some of these more advanced topics in the sections that follow. This section provides a general overview of the JAX-RPC specification and the ref- erence implementation included with the JWSDP. Chapter 34, Apache Axis, pro- vides a detailed look at a more complete implementation of this specification. Cross- Reference o538292 ch33.qxd 8/18/03 8:45 AM Page 760 761 Chapter 33 ✦ Web Services with the Sun Java Web Services Developer Pack Figure 33-4: JAX-RPC overview WSDL at work As you begin to work with any JAX-RPC implementation, you’re likely to find that WSDL (Web Services Description Language) is going to represent the logical start- ing point for developing any client or service. WSDL is a standardized markup lan- guage that is used to express the interface contract that is published by any Web Service. It defines the set of valid operations that are exposed for a given service as well as any parameters that are included in the signature of these operations. JAX-RPC takes advantage of this standardized service specification, using it as the source for generating client and service Java classes that correspond to a service’s interface (see Figure 33-5). Client Application JAX-RPC Stubs Web Service Clients JAX-RPC Run-Time JAX-RPC Run-Time JAX-RPC Ties Web Services Service Endpoint SOAP o538292 ch33.qxd 8/18/03 8:45 AM Page 761 [...]... the native registries JAXR Clients Browser Client Swing Client Other Client JAXR API UDDI Provider ebXML Provider UDDI/SOAP UDDI Registry Other Provider ebXML/SOAP ebXML Registry Other Registry Figure 33-6: JAXR architecture Every provider must implement the APIs from the javax .xml. registry and javax .xml. registry.infomodel packages The later of these two is where registry objects are actually transformed... props.setProperty(“javax .xml. registry.queryManagerURL”, “http://uddi.ibm.com/testregistry/inquiryapi”); props.setProperty(“javax .xml. registry.lifeCycleManagerURL”, “https://uddi.ibm.com/testregistry/protect/publishapi”); props.setProperty(“com.sun .xml. registry.http.proxyHost”, “myhost.mydomain”); props.setProperty(“com.sun .xml. registry.http.proxyPort”, “8080”); ConnectionFactory connFactory = ConnectionFactory.newInstance();... most limiting factors of the Apache SOAP implementation A key contributor to these performance problems was the system’s XML processor, which used the DOM (Document Object Model) for processing the XML stream This problem was addressed by making the switch to SAX (Simple API for XML Parsing), which reduced memory consumption and offered generally faster parsing of the message stream This switch alone... TestDynamicClient.java import import import import import org.apache.axis.AxisFault; org.apache.axis.client.Call; org.apache.axis.client.Service; org.apache.axis.encoding.XMLType; org.apache.axis.utils.Options; import javax .xml. namespace.QName; import javax .xml. rpc.ParameterMode; import java.net.URL; public class TestDynamicClient { public String getAnswer(String question) { String answer = “Failure”; try { URL... API has to offer 7 69 770 Part VII ✦ Web Services and J2EE Getting a connection Before you can start interacting with a registry, you’ll need to get a connection The JAXR API uses a property-based approach to acquiring a “configured” connection The following code provides a simple example of opening a JAXR connection: Properties props = new Properties(); props.setProperty(“javax .xml. registry.queryManagerURL”,... functionality offered by both UDDI and ebXML Its flexible architecture supports both of these standards and, in doing so, puts in place a framework that will evolve with these standards and others that may be introduced in the future Capability profiles JAXR’s challenge of being a true union of the exiting registries required some quick thinking UDDI and ebXML both include their own unique sets of... and Integration) and ebXML These two registry schemes are by far the most popular and most heavily used The existence of two competing standards, in some respect, is what created the need for JAXR With two standards already in place, both with their own feature set, it became important for developers to have an API that kept them from being so tightly coupled to the UDDI or ebXML implementations Developers... JAXR information model Developers will need to acclimate themselves to this new model and how it represents each native registry type If you’re familiar with the ebXML model, the transitions shouldn’t be that difficult since many of the ebXML model elements map very directly to their JAXR counterparts A few registry scenarios There is a multitude of operations and uses for JAXR that could vary widely... Service(); Call call = (Call)service.createCall(); call.setTargetEndpointAddress(server_url); call.setOperationName(new QName(“”, “getPrediction”)); call.addParameter(“question”, XMLType.XSD_STRING, ParameterMode.IN); call.setReturnType(XMLType.XSD_STRING); Chapter 34 ✦ Apache Axis Object ret = call.invoke(new Object[]{question}); answer = (String)ret; } catch(Exception e) { e.printStackTrace(); } return answer;... actually dictate strict requirements for these tools In fact, when we look at Apache’s Axis in Chapter 34, we’ll find that it has its own twist on how to address this area of functionality Java API for XML Registries (JAXR) So, with all this talk of Web Services one wonders how, in the vast world of the Internet, we are supposed to know what services are available and what features are offered by each . factory is acquired as follows: MessageFactory ebXMLFactory = provConn.createMessageFactory(“ebxml”); EbXMLMessageImpl ebXMLMessage = (EbXMLMessageImpl)ebxmlFactory.createMessage(); In this example,. Message <SOAP-ENV:Envelope xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/” <SOAP-ENV:Body> <ASTRO:GetHoroscope xmlns:ASTRO=”http://www.astro.com”> <DateOfBirth>05/03/ 196 4</DateOfBirth> <FavoriteColor>Purple</FavoriteColor> </ASTRO:GetHoroscope> </SOAP-ENV:Body> </SOAP-ENV:Envelope>. made part of the javax .xml. soap package. JAXM still retains its dependency on the javax .xml. soap pack- age (as it should), but javax .xml. soap has no dependency on javax .xml. messaging. This move

Ngày đăng: 09/08/2014, 18:22

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN