Teach Yourself J2EE in 21 Days phần 9 pptx

113 279 0
Teach Yourself J2EE in 21 Days phần 9 pptx

Đ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

Using RPC-Style Web Services with J2EE 879 20 The other type of J2EE component in which application logic can be held is a servlet or JSP. You may ask how you would wrap this functionality for use as a Web Service. Well, the issue here is that many of the Web components in question are already acting as channels to some form of client (as shown in Figure 20.4). Consequently, wrapping them makes no sense. What you should do is create a replacement for such a Web component that is targeted at Web Service clients rather than Web browsers. If your Web compo- nents are well designed, you should be able to reuse the JavaBeans, servlet filters, and helper classes (even servlets/JSPs that they use) as part of your Web Service implementa- tion. If you already have servlets or JSPs that generate XML, you might be able to migrate them to meet your Web Service needs or transform the generated XML as part of the solution. Using an RPC-style SOAP-Based Web Service SOAP grew out of an effort to create an XML-based method invocation mechanism for distributed objects (primarily Microsoft’s DCOM). As such, it is an ideal transport for method calls made over Web Services. F IGURE 20.4 Web Services are just another channel through which to access business func- tionality. J2EE Server Web Service Client Browser Client Mobile Client SOAP Request SOAP Response HTML Request HTML Response WML Request WML Response EJBs SOAP servlet HTML servlet WAP servlet 24 0672323842 CH20 3/20/02 9:22 AM Page 879 RPC-Oriented Web Services Remote Procedure Calls (RPCs) made over Web-based protocols are essentially no dif- ferent from those made over other protocols, such as IIOP, DCOM, or JRMP. The calls are usually synchronous (in other words, the client waits for the method to return before continuing). Zero or more parameters of varying types are passed into the call to provide information to process, and zero or more return values are generated to deliver the out- puts of the remote method to the client. The remote method calls are delivered to some form of dispatcher at the remote server that determines which method should be called and arranges for the smooth flow of parameters and return values. For RPC-style operation, SOAP implementations conform to the preceding description. The difference with SOAP (and other Web-based RPC mechanisms, such as XML-RPC) is that it uses standard, general-purpose transports, such as HTTP, together with a text- based method call description in XML. All of the parameters and return values are encoded in XML as part of the SOAP body, while information about the service and method to call are provided in the transport header and possibly the SOAP header. When sent over HTTP, the SOAP header and body are wrapped in another XML document— the SOAP envelope—and this envelope forms the body of an HTTP POST request. An HTTP-based SOAP message will be delivered to a SOAP router that takes the form of an HTTP servlet (for a Java implementation). The SOAP router will examine the HTTP and SOAP header information and decide how it should forward the message body. This will involve instantiating or calling a particular component or class that will receive the message. The SOAP router, or its helper classes, will also perform the con- version of the XML-based parameters into Java objects and primitives that can be passed as part of the service invocation. Figure 20.5 shows the operation of such a SOAP router. Note that the description of the Web Service is used by both the client and server to help determine the correct mapping between Java and XML for method calls and parameter types. This is all good, but why go to this effort? Why not use an existing RPC mechanism, such as RMI or just use HTTP itself? The justification for not using RMI or CORBA relates to commonality and security. There are at least three different distributed object protocols (CORBA, RMI, and DCOM), each of which has its adherents. The use of HTTP and XML provides a com- mon protocol that is not tied to any vendor. Also, the protocols listed have great difficulty in penetrating most firewalls (not surprising, given their ability to invoke random func- tionality). However, HTTP (and SMTP) have general right of access through most fire- walls, which makes it easier to integrate applications across organizational boundaries (after the security questions are sorted out). 880 Day 20 24 0672323842 CH20 3/20/02 9:22 AM Page 880 Using RPC-Style Web Services with J2EE 881 20 Although raw HTTP is a good transport, it was created to exchange simple HTML mes- sages. This does not provide the sophistication required for a distributed invocation envi- ronment. The use of a defined XML message format brings structure to this environment and allows for the interoperability of Web Service clients and servers from different vendors—something that escaped CORBA until comparatively recently. Now that you understand the architecture and motivation for RPC-style Web Services, you can install a Java-based Web Service environment and, through it, use and build your own Web Services. Setting up Axis under Tomcat 4.0 The environment you will use for Web Service development in the first instance consists of the Tomcat servlet engine and the Axis Web Service toolkit, both from the Apache Software Foundation. F IGURE 20.5 A Java-based SOAP router. Web Service Proxy EJBs SOAP Router and Dispatcher servlet Web Service Client Candidate Web Services SOAP Request SOAP Response Java methods Invoke target method servlets Java WSDL From a developer’s perspective, one of SOAP’s greatest assets is its ability to penetrate firewalls. However, from an administrator’s point of view, this pre- sents the same types of problem as traditional RPC, namely the ability to tar- get a random function call at an exposed server. Although the principle of SOAP is only a small step on from the invocation of server-side functionality such as CGI, great care should be taken to ensure adequate security when exposing Web Services. The overall security story for Web Services is still a work in progress. Caution 24 0672323842 CH20 3/20/02 9:22 AM Page 881 You can download Tomcat 4.0 from the Apache Software Foundation at http://jakar- ta.apache.org/tomcat/ or install it from the CD-ROM as follows: 1. Unzip the Tomcat 4.0 archive (jakarta-tomcat-4.0.1.zip) into an appropriate directory on your hard drive (an example from Windows would be C:\jakarta- tomcat-4.0.1). 2. In your personal or system environment, set the environment variable CATALINA_HOME to point to this directory. You can download Axis from the Apache Software Foundation or install it from the CD- ROM as follows: • Unzip the Axis archive (xml-axis-alpha2-bin.zip) into an appropriate directory on your hard drive (an example from Windows would be C:\axis-1_0). • Copy the webapps\axis directory from the axis-1_0 distribution into Tomcat’s webapps directory ({CATALINA_HOME}\webapps). You need to install XML support for Axis from the Fall 01 JAX Pack (available from Sun or on the CD-ROM) as follows: • Unzip the JAX Pack archive (java_xml_pack-fall01.zip) into an appropriate directory on your hard drive (an example from Windows would be C:\java_xml_pack-fall01). • Copy crimson.jar and xalan.jar from the jaxp-1.1.3 directory into axis\WEB- INF\lib under Tomcat’s webapps directory ({CATALINA_HOME}\webapps). Tomcat and Axis are now installed with the appropriate XML support. In the next section, you will create a client for a simple hello Web Service. First, you must install and test this simple Web Service as follows: 1. Install the class required for the HelloService by copying the webservices direc- tory from the CD-ROM directory Day20\examples\HelloService to axis\WEB- INF\classes under Tomcat’s webapps directory ({CATALINA_HOME}\webapps). 2. Start Tomcat by running the startup script/batch file in the {CATALINA_HOME}\bin directory. 3. To ensure that Tomcat and Axis are installed correctly, start a Web browser and point it at http://localhost:8080/axis/index.html. You should see a welcome screen from Axis. • Now deploy the hello server using the deployit batch file in the CD-ROM directory Day20\examples\HelloService. 882 Day 20 24 0672323842 CH20 3/20/02 9:22 AM Page 882 Using RPC-Style Web Services with J2EE 883 20 Assuming that you had no errors, you have now deployed a simple Web Service called MyHelloService. In the long and distinguished tradition of curly-bracket-based lan- guages, you will start with a variation on the Hello World! program. Service Description Information Your Web server now has a Web Service installed under it. The next step is to access that Web Service. However, before you can take advantage of the Web Service, you need the following information: • A definition of the service you are calling—This information corresponds to the traditional interface definition for an RPC or RMI server. The interface definition contains information about the methods available, the number and types of parame- ters, the type of any return values, and definitions of any complex types used as parameters. • The location of the service—This corresponds to the binding information used by RPC and RMI servers. This Web Service binding information lists the protocols over which you can call the available Web Service methods. For each supported protocol, there is also a URL indicating the location of a server that provides an implementation of that service for that protocol. As you may have surmised by now, all of this information is provided by a WSDL description of the service. Anatomy of a WSDL Document The WSDL for MyHelloService is shown in Listing 20.1. It is worth taking a few moments to study this information because it provides a good insight into the way that Web Services work. LISTING 20.1 WSDL for the Hello Service (MyHelloService.wsdl) 1: <?xml version=”1.0” encoding=”UTF-8”?> 2: 3: <definitions 4: targetNamespace=”http://localhost:8080/axis/services/MyHelloService” 5: xmlns:xsd=”http://www.w3.org/2001/XMLSchema” 6: xmlns:serviceNS=”http://localhost:8080/axis/services/MyHelloService” 7: xmlns:soap=”http://schemas.xmlsoap.org/wsdl/soap/” 8: xmlns=”http://schemas.xmlsoap.org/wsdl/”> 9: 10: <message name=”sayHelloToRequest”> 11: <part name=”arg0” type=”xsd:string”/> 12: </message> 13: 14: <message name=”sayHelloToResponse”> 24 0672323842 CH20 3/20/02 9:22 AM Page 883 15: <part name=”sayHelloToResult” type=”xsd:string”/> 16: </message> 17: 18: <portType name=”HelloServerPortType”> 19: <operation name=”sayHelloTo”> 20: <input message=”serviceNS:sayHelloToRequest”/> 21: <output message=”serviceNS:sayHelloToResponse”/> 22: </operation> 23: </portType> 24: 25: <binding name=”HelloServerSoapBinding” ➥ type=”serviceNS:HelloServerPortType”> 26: <soap:binding style=”rpc” ➥ transport=”http://schemas.xmlsoap.org/soap/http”/> 27: <operation name=”sayHelloTo”> 28: <soap:operation soapAction=”” style=”rpc”/> 29: <input> 30: <soap:body use=”encoded” 31: encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” 32: namespace=”MyHelloService”/> 33: </input> 34: <output> 35: <soap:body use=”encoded” 36: encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/” 37: namespace=”MyHelloService”/> 38: </output> 39: </operation> 40: </binding> 41: 42: <service name=”HelloServer”> 43: <port name=”HelloServerPort” ➥ binding=”serviceNS:HelloServerSoapBinding”> 44: <soap:address ➥ location=”http://localhost:8080/axis/services/MyHelloService”/> 45: </port> 46: </service> 47: 48: </definitions> The document consists of the following sections: • The XML prolog and root element (lines 1–8 and 48). The namespace declarations on the root element (definitions) show that all unqualified elements and attribut- es come from the WSDL schema. The soap prefix denotes types from the SOAP schema, while the xsd prefix denotes types from the W3C XML Schema defini- tion. There is also a namespace defined for this service that is associated with the serviceNS prefix. 884 Day 20 LISTING 20.1 Continued 24 0672323842 CH20 3/20/02 9:22 AM Page 884 Using RPC-Style Web Services with J2EE 885 20 • WSDL message definitions (lines 10–16). These define two matched messages—a request and a response. The request (sayHelloToRequest) takes a single string parameter and the response (sayHelloToResponse) also returns a single string. • WSDL portType definitions (lines 18–23). A portType is the equivalent of an interface definition. It contains one or more operation definitions, which in turn are built from the message definitions in the document. In this case, there is a sin- gle operation defined in the HelloServerPortType called sayHelloTo. This con- sists of the two messages, sayHelloToRequest and sayHelloToResponse, seen ear- lier. • Now that you have an interface (portType), you can define the protocols over which that interface can be accessed. The binding element (lines 25–40) creates a binding, called HelloServerSoapBinding, between the HelloServerPortType and SOAP. Within this WSDL binding, a SOAP binding (soap:binding) is defined. Because SOAP can work with a variety of underlying transports and it can work in an RPC-centric or document-centric way, the attributes on the soap:binding indi- cate that it is an RPC-style binding that uses HTTP. The WSDL operation is then mapped to a SOAP operation with input and out- put soap:body elements defined to map the request and response. • Finally, an instance of the service is defined in the WSDL service element (lines 42–46). A WSDL service contains a list of WSDL port elements. Each port ele- ment defines a specific instance of a server that conforms to one of the WSDL bindings defined earlier. Again, in the case of the simple Hello service, the service element (named HelloServer) contains a single WSDL port called HelloServerPort. This speci- fies that a server conforming to the HelloServerSoapBinding can be found at the given SOAP address, namely http://localhost:8080/axis/service/MyHelloService. This is a very simple WSDL document defining a very simple service. WSDL documents are typically far longer and more complex. Because of this, WSDL is largely intended for manipulation by tools and applications. Creating a Java Proxy from WSDL Given the service description in Listing 20.1, the next step is to create a client that can use this service. The simplest way to do this is to have a tool generate a proxy for the service. This proxy will be a local object that will hide away a lot of the complexity associated with the mechanics of calling methods on the service. You can apply the Apache Axis Wsdl2java tool to MyHelloService.wsdl as follows java org.apache.axis.wsdl.Wsdl2java MyHelloService.wsdl 24 0672323842 CH20 3/20/02 9:22 AM Page 885 This will generate three Java files: • HelloServerPortType.java is a Java interface that represents the remote interface (or portType in WSDL terms). This is shown in Listing 20.2. Note that the inter- face looks like an RMI interface in that it extends java.rmi.Remote, and the method is defined as throwing java.rmi.RemoteException. The service proxy implements this interface, and the client should use the interface type to reference instances of the service proxy. • HelloServer.java is a factory class that creates instances of the service proxy. This is shown in Listing 20.3. The client instantiates a factory and then calls the getHelloServerPort method to obtain a service proxy. Two forms of this method are provided—one that allows the client to specify the endpoint at which the ser- vice resides and the other that takes no arguments. The latter method will use the location information contained in the WSDL file when instantiating the service proxy. • HelloServerSoapBindingStub.java is the service proxy itself. Note that by using a separate interface to represent the portType and a factory for the creation of the proxy, the same client code can be used, regardless of the particular protocol bind- ing. The code for HelloServerSoapBindingStub.java is not shown here because it is very similar to the “raw” SOAP code you will see shortly. LISTING 20.2 HelloServerPortType.java 1: /** 2: * HelloServerPortType.java 3: * 4: * This file was auto-generated from WSDL 5: * by the Apache Axis Wsdl2java emitter. 6: */ 7: 7: 8: public interface HelloServerPortType extends java.rmi.Remote { 9: public String sayHelloTo(String arg0) throws java.rmi.RemoteException; 10: } 886 Day 20 To run the tools and compile the files, you must have the JAR files from the axis\WEB-INF\lib directory on your classpath, namely axis.jar, clutil.jar, crimson.jar, log4j-core.jar, wsdl4j.jar, and xalan.jar. Note 24 0672323842 CH20 3/20/02 9:22 AM Page 886 Using RPC-Style Web Services with J2EE 887 20 LISTING 20.3 HelloServer.java 1: /** 2: * HelloServer.java 3: * 4: * This file was auto-generated from WSDL 5: * by the Apache Axis Wsdl2java emitter. 6: */ 7: 8: public class HelloServer { 9: 10: // Use to get a proxy class for HelloServerPort 11: private final java.lang.String HelloServerPort_address = 12: “http://localhost:8080/axis/services/MyHelloService”; 13: public HelloServerPortType getHelloServerPort() { 14: java.net.URL endpoint; 15: try { 16: endpoint = new java.net.URL(HelloServerPort_address); 17: } 18: catch (java.net.MalformedURLException e) { 19: return null; // unlikely as URL was validated in wsdl2java 20: } 21: return getHelloServerPort(endpoint); 22: } 23: 24: public HelloServerPortType ➥ getHelloServerPort(java.net.URL portAddress) { 25: try { 26: return new HelloServerSoapBindingStub(portAddress); 27: } 28: catch (org.apache.axis.SerializationException e) { 29: return null; // ??? 30: } 31: } 32: } You can now write a client application that uses these classes. The code for such an application is shown in Listing 20.4. This application simply takes the name passed as a parameter and sends it to the sayHelloTo method of the Web Service. You can see the creation of the HelloServer service proxy factory on line 20. The client then calls the getHelloServerPort method to obtain an instance of the service proxy (line 23). The client can then call the sayHelloTo method passing the given parameter (line 28). This method invocation is wrapped in a try-catch block to catch any potential RemoteException that may occur. 24 0672323842 CH20 3/20/02 9:22 AM Page 887 LISTING 20.4 HelloServerClient.java Application That Uses Generated Service Proxy 1: import java.rmi.RemoteException; 2: 3: public class HelloServerClient 4: { 5: public static void main(String [] args) 6: { 7: String name = “unknown”; 8: 9: if (args.length != 1) 10: { 11: System.out.println(“Usage: WebServiceSayHello <name>”); 12: System.exit(1); 13: } 14: else 15: { 16: name = args[0]; 17: } 18: 19: // Instantiate the factory 20: HelloServer factory = new HelloServer(); 21: 22: // Get a PortType that represents this particular service 23: HelloServerPortType service = factory.getHelloServerPort(); 24: 25: try 26: { 27: // Call the service 28: String response = service.sayHelloTo(name); 29: 30: System.out.println(response); 31: } 32: catch(RemoteException ex) 33: { 34: System.out.println(“Remote exception: “ + ex); 35: } 36: } 37: } To test out your client, you should: 1. Compile the client code. 2. Ensure that the service is running (both Tomcat and the Axis server). 3. Run the client (with the appropriate classpath settings) as shown prompt> java HelloServerClient Fred Hello Fred! 888 Day 20 24 0672323842 CH20 3/20/02 9:23 AM Page 888 [...]... CH20 3/20/02 9: 23 AM Page 90 5 Using RPC-Style Web Services with J2EE LISTING 20.14 90 5 Continued 31: 32: 35: 36: 37: 38: 39: 41:... to make best use of them Failing that, you would certainly want to retain resources between client invocations that form part of the same workflow (or transaction) Issues surrounding resource recycling and scalability have already been discussed on Day 18, “Patterns.” 24 0672323842 CH20 3/20/02 9: 23 AM Page 90 9 Using RPC-Style Web Services with J2EE 90 9 Wrapping Existing J2EE Functionality as Web Services... AM Page 891 Using RPC-Style Web Services with J2EE 891 A SOAP Call is then instantiated (line 37) and populated with the service name (line 39) and the method name (line 40) The parameters for the call must be encoded as Parameter instances, specifying the parameter name, Java class, and encoding required A java.util.Vector containing all of the parameters is then passed to the Call object (lines 42–46)... SOAP code in Listing 20.5 because the code surrounding the call setup has been largely simplified Dynamic calling will be examined further tomorrow in the discussion surrounding the use of directory services 20 24 0672323842 CH20 3/20/02 9: 23 AM Page 892 892 Day 20 Debugging a SOAP Interaction As with any distributed environment, debugging Web Service interaction is a challenge One of the main issues... when trying to marshal or unmarshal these types LineItemBean.java—Encapsulating the Product Information in a JavaBean 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: package webservices; public class LineItemBean { private String _productCode; private int _quantity; public LineItemBean(String productCode, int quantity)... SimpleOrderServerSoapBindingSkeleton 9: { 10: private SimpleOrderServerPortType impl; 11: 12: public SimpleOrderServerSoapBindingSkeleton() 13: { 14: this.impl = new SimpleOrderServerSoapBindingImpl(); 15: } 16: 17: public ➥ SimpleOrderServerSoapBindingSkeleton(SimpleOrderServerPortType impl) 18: { 19: this.impl = impl; 20: } 21: 22: public Object submitOrder(String arg0, String arg1, int arg2) 23: throws... Under Axis, simply setting state on the server side will have no effect unless the client also indicates that it wants to maintain session state To do this, the client calls the setMaintainSession on the client-side service proxy, as shown in the altered client in Listing 20.17 on lines 30–32 LISTING 20.17 Client Code Altered to Work with the SessionSimpleOrderServer to Maintain Session... 24: { 20 24 0672323842 CH20 3/20/02 9: 23 AM Page 90 2 90 2 Day 20 LISTING 20.10 25: 26: 27: 28: } Continued Object ret = impl.submitOrder(arg0, arg1, arg2); return ret; } LISTING 20.11 SimpleOrderServerSoapBindingImpl.java—A Skeleton Within Which to Implement Your Business Logic 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: /** * SimpleOrderServerSoapBindingImpl.java * * This file was auto-generated... System.err.println(“Generated fault: “); System.out.println (“ Fault Code = “ + fault.getFaultCode()); System.out.println (“ Fault String = “ + fault.getFaultString()); } The first thing to notice is that the endpoint URL is now split into the service name and the SOAP router (lines 8 and 9) This SOAP router URL must be turned into a java.net.URL (lines 25–35) for it to be used 24 0672323842 CH20 3/20/02 9: 23... 3/20/02 9: 23 AM Page 90 6 90 6 Day 20 The only time that the “Hello again” greeting will be seen is if session state has been maintained between invocations LISTING 20.15 SessionSimpleOrderServer.java—A Version of the Simple Order Server That Maintains Session State 1: package webservices; 2: 3: public class SessionSimpleOrderServer 4: { 5: private String lastCustomer = “”; 6: 7: public ➥String submitOrder(String . the following information: • A definition of the service you are calling—This information corresponds to the traditional interface definition for an RPC or RMI server. The interface definition contains. you have an interface (portType), you can define the protocols over which that interface can be accessed. The binding element (lines 25–40) creates a binding, called HelloServerSoapBinding, between. HelloServerPortType and SOAP. Within this WSDL binding, a SOAP binding (soap:binding) is defined. Because SOAP can work with a variety of underlying transports and it can work in an RPC-centric or document-centric

Ngày đăng: 13/08/2014, 08:21

Tài liệu cùng người dùng

Tài liệu liên quan