Sunteți pe pagina 1din 107

Oracle Certified Expert, Java Platform, Enterprise Edition 6 Web Services Developer Study Guide Next

Oracle Certified Expert, Java Platform, Enterprise Edition 6 Web Services Developer Study Guide
Mikalai Zaikin
IBA JV Belarus Minsk

<NZaikin[at]iba.by>
Copyright 2012 Mikalai Zaikin Redistribution of this document is permitted as long as it is not used for profits. July 2012
Revision History Revision $Revision: 120 $ $Date: 2012-07-21 22:34:48 +0300 (, 21 2012) $ $Id: ocewsd6-guide.xml 120 2012-07-21 19:34:48Z mzaikin $

$Author: mzaikin $

Abstract The purpose of this document is to help in preparation for Java Platform, Enterprise Edition 6 Web Services Developer Certified Expert Exam (CX-310-232). This document should NOT be used as the only study material for "Oracle Certified Expert Web Services Developer for Java EE6" test (a.k.a. SCDJW S 6). It covers the Beta Test objectives, w hich may not match the Production Test objectives. I tried to make this document as much accurate as possible, but if you find any error, please let me know . Preface I. Exam Objectives 1. Create an SOAP w eb service in a servlet container 1.1. Create a w eb service starting from a W SDL file using JAX-W S 1.1.1. Use wsimport tool to generate artifacts from W SDL 1.1.2. Use external and embedded <jaxws:package>, <jaxws:enableWrapperStyle>, <jaxws:class> customizations 1.1.3. Use JAXB customizations to configure mapping. 1.1.4. Build the w eb service implementation using the above artifacts. 1.1.5. Access MessageContext.SERVLET_CONTEXT from the injected @WebServiceContext 1.1.6. Configure deployment descriptors ( web.xml, webservices.xml) for URL patterns, HTTP security, container authorization, caller authentication, and message protection. JAX-W S runtime may also be configured to perform message layer authentication and protection. 1.1.7. Compile and package the w eb service into a W AR file 1.1.8. Deploy the w eb service into a Java EE servlet container 1.2. Create a w eb service starting from a W SDL file using JAX-W S 1.2.1. Use @WebService to indicate a service 1.2.2. Use @WebMethod, @WebMethod(exclude) to indicate service methods 1.2.3. Use @SOAPBinding to select doc/lit, doc/bare, rpc/lit style of w eb service 1.2.4. Use @Oneway w here the service doesn't have any response 1.2.5. Use @WebParam, and @WebResult to customize parameter and operation names 1.2.6. Use checked exceptions to indicate service specific faults. 1.2.7. Use wsgen tool to generate artifacts in Java EE5 (optional in Java EE6, as artifacts are generated at run time). 1.2.8. Configure deployment descriptors ( web.xml, webservices.xml) for URL patterns, HTTP security, container authorization, caller authentication, and message protection. JAX-W S runtime may also be configured to perform message layer authentication and protection. 1.2.9. Compile and package the w eb service into a W AR file 1.2.10. Deploy the w eb service into a Java EE servlet container 2. Create a RESTful w eb service in a servlet container 2.1. Create a w eb service using JAX-RS, refer to Jersey implementation for examples 2.1.1. Annotate a class w ith a @Path annotation to respond to URI templates. 2.1.2. Annotate the class's methods to respond to HTTP requests using the corresponding JAX-RS annotations ( @GET, @POST, etc.). 2.1.3. Use the JAX-RS @Consumes and @Produces annotations to specify the input and output formats for the RESTful w eb service. 2.1.4. Use @PathParam, @QueryParam, @MatrixParam and @HeaderParam to extract request data. 2.1.5. Use the UriInfo and UriBuilder to create URIs that refer to resources in the service. 2.1.6. Use ResponseBuilder to create response w ith customized status and additional metadata. 2.1.7. Implement a MessageBodyReader and MessageBodyWriter to add support for custom request and response data types 2.1.8. Implement ExceptionMapper to map a custom Exception to a response. 2.1.9. Use Request to add support for HTTP preconditions. 2.1.10. Implement the functionality of the JAX-RS resource's methods. 2.1.11. Use @Path on a method to define a subresource. 2.1.12. Configure deployment descriptor ( web.xml) for base URL pattern, HTTP security (via security-constraints in web.xml) 2.1.13. Compile and package 2.1.14. Deploy the w eb service in a Java EE servlet container 3. Create a SOAP based w eb service implemented by an EJB component 3.1. Create a w eb service starting from a W SDL file using JAX-W S

converted by Web2PDFConvert.com

3.1.1. Use wsimport tool to generate artifacts and use customization files for w simports if needed 3.1.2. Create an EJB w eb service implementations using annotations ( @Stateless or @Singleton) 3.1.3. Configure deployment descriptors ( ejb-jar.xml, webservices.xml) for transactions, etc. 3.1.4. Configure container role based access control via method-permissions in ejb-jar.xml or via access control annotations on EJB. 3.1.5. Configure caller authentication and message protection; either by Servlet Container via web.xml, and/or by JAX-W S message processing runtime. 3.1.6. Compile and package the w eb service into a EAR/W AR file (Java EE 6 - W AR can also have EJBs). 3.1.7. Deploy the w eb service into a Java EE container. 3.2. Create a w eb service starting from a Java source using JAX-W S 3.2.1. 3.2.2. 3.2.3. 3.2.4. 3.2.5. 3.2.6. Use wsgen tool to generate artifacts in Java EE5 from EJB classes (optional in Java EE 6 - as artifacts are generated at run time). Configure deployment descriptors ( ejb-jar.xml, webservices.xml) for transactions, etc. Configure container role based access control via method-permissions in ejb-jar.xml or via access control annotations on EJB. Configure caller authentication and message protection; either by Servlet Container via web.xml, and/or by JAX-W S message processing runtime. Compile and package the w eb service into a W AR/EAR file. Deploy the w eb service into a Java EE container.

4. Create a RESTful w eb service implemented by an EJB component 4.1. Create a w eb service using JAX-RS from EJB classes. 4.1.1. Annotate an enterprise bean class w ith a @Path annotation to respond to URL patterns. 4.1.2. Annotate the class's methods to respond to HTTP requests using the corresponding JAX-RS annotations ( @GET, @POST, etc.). 4.1.3. Use the JAX-RS @Produces and @Consumes annotations to specify the input and output resources for the RESTful w eb service. 4.1.4. Implement the functionality of the JAX-W S resource's methods. 4.1.5. Configure container role based access control via method-permissions in ejb-jar.xml or via access control annotations on EJB. 4.1.6. Configure caller authentication (for access control protected methods) and message protection by Servlet Container via web.xml. 4.1.7. Compile and package. 4.1.8. Deploy the w eb service in a Java EE servlet container. 5. Configure Java EE security for a SOAP w eb service 5.1. Configure security requirements of service using Java EE-container based security (overlaps w ith steps in other tasks - repeated here for convenience) 5.1.1. Configure security requirements through deployment descriptors ( web.xml, webservices.xml) for a Servlet-based w eb service endpoint: container authorization, caller authentication, and message protection. JAX-W S runtime may also be configured to perform message layer authentication and protection. 5.1.2. Configure security requirements through deployment descriptors ( ejb-jar.xml, webservices.xml) for EJB-based w eb service endpoint: 5.1.3. Configure security requirements through deployment descriptor ( web.xml) for JAX-RS based w eb service endpoint. 6. Create a w eb service client for a SOAP based w eb service 6.1. Create a standalone client. 6.1.1. Use wsimport to generate artifacts. 6.1.2. Create a client application using these artifacts. 6.1.3. Package and deploy accordingly. 6.2. Create a client in a managed component in a EE container. 6.2.1. Use wsimport to generate artifacts. 6.2.2. Using @WebserviceRef in the client application. 6.2.3. Package and deploy accordingly. 7. Create a w eb service client for a RESTful w eb service 7.1. 7.2. 7.3. 7.4. 7.5. 7.6. Use Use Use Use Use Use a brow ser to access a JAX-RS resource the java.net.* APIs to access a JAX-RS resource. java.net.Authenticator to access a secure JAX-RS resource. Ajax to access a JAX-RS resource. the Jersey client API to access a JAX-RS resource. the JAX-W S HTTP binding to access a JAX-RS resource.

8. Create a SOAP based w eb service using Java SE platform. 8.1. Create a w eb service starting from a W SDL file using JAX-W S. 8.1.1. Use wsimport tool to generate artifacts and use customization files for w simports if needed. 8.1.2. Build the w eb service implementation using the above artifacts. 8.1.3. Use Endpoint API to configure and deploy it in Java SE 6 platform. 8.2. Create a w eb service starting from a Java source using JAX-W S. 8.2.1. Use wsgen tool to generate artifacts in Java EE5 (optional in Java EE6 - as artifacts are generated at run time) 8.2.2. Use Endpoint API to configure and deploy it in Java SE 6 platform. 9. Create handlers for SOAP w eb services. 9.1. Configure SOAP and logical handlers on the server side. 9.1.1. Use @HandlerChain annotation. 9.1.2. Use deployment descriptors. 9.2. Configure SOAP and logical handlers on the client side. 9.2.1. Use deployment descriptors. 9.2.2. Use programmatic API. 10. Create low -level SOAP w eb services. 10.1. Describe the functions and capabilities of the APIs included w ithin JAXP. 10.2. Describe the functions and capabilities of JAXB, including the JAXB process flow , such as XML-to-Java and Java-to-XML, and the binding and validation mechanisms provided by JAXB. 10.3. Use Provider API to create a w eb service. 10.3.1. Process the entire SOAP message, using the SAAJ APIs. 10.3.2. Process only the SOAP body, using JAXB. 10.4. Use Dispatch API to create a dynamic w eb service client.

converted by Web2PDFConvert.com

11. Use MTOM and MIME in a SOAP w eb service. 11.1. Use MTOM on the service. 11.1.1. 11.1.2. 11.1.3. 11.1.4. 11.1.5. 11.1.6. Use Use Use Use Use Use

@MTOM annotation w ith a w eb service.


MTOM policy in W SDL. MTOM in the deployment descriptors MTOMFeature w ith javax.xml.ws.Endpoint API swaRef in W SDL. MIME binding in W SDL

11.2. Use MTOM on the client. 11.2.1. Use MTOMFeature w ith getPort() methods. 11.2.2. Use MTOM in the deployment descriptors. 11.2.3. Sending any additional attachments using MessageContext properties. 12. Use W S-Addressing w ith a SOAP w eb service 12.1. Use Addressing on the service 12.1.1. 12.1.2. 12.1.3. 12.1.4. 12.1.5. 12.1.6. Use Use Use Use Use Use

@Addressing annotation w ith a w eb service wsam:Addressing policy in W SDL


Addressing in the deployment descriptors AddressingFeature w ith javax.xml.ws.Endpoint API. @Action and @FaultAction on the service methods.

WebServiceContext.getEndpointReference()

12.2. Use Addressing on the client. 12.2.1. 12.2.2. 12.2.3. 12.2.4. Use Use Use Use

AddressingFeature w ith getPort() methods.


Addressing in the deployment descriptors

BindingProvider.getEndpointReference() getPort(EndpointReference) methods.

13. Configure Message Level security for a SOAP w eb service 13.1. Select the appropriate Security Profile for your service. The selection w ould be based on a match of the Protection guarantees offered by the profile and those required by the service. 13.2. Configure Username/Passw ord callbacks required by the Username Token Profile. 13.3. Configure any server side Validators as maybe applicable for the profile. There are defaults in GlassFish for most of them. 13.4. Optimize interaction betw een client and server by using W S-SecureConversation. 14. Apply best practices to design and implement w eb services. 14.1. 14.2. 14.3. 14.4. II. Appendices 1. To be added 1.1. To be added
Next Preface

Use different encoding schemes - fast infoset. Use GZIP for optimiziing message sizes. Use catalog mechanism for W SDL access. Refer to W S-I sample app for best practices.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 1. Create an SOAP web service in a servlet container Part I. Exam Objectives

Next

Chapter 1. Create an SOAP web service in a servlet container 1.1. Create a web service starting from a WSDL file using JAX-WS
1.1.1. Use wsimport tool to generate artifacts from WSDL
JAX-W S provides the wsgen and wsimport command-line tools to generate portable artifacts for JAX-W S w eb services. W hen creating JAX-W S w eb services, you can start w ith either a W SDL file or an implementation bean class. If you start w ith an implementation bean class, use the wsgen command-line tool to generate all the w eb services provider artifacts, including a W SDL file if requested. If you start w ith a WSDL file, use the wsimport command-line tool to generate all the w eb services artifacts for either the server or the client. The wsimport command-line tool processes the W SDL file w ith schema definitions to generate the portable artifacts, w hich include the service class, the service endpoint interface class, and the JAXB 2.1 classes for the corresponding XML schema. The wsimport tool generates JAX-W S portable artifacts, such as: Service Endpoint Interface (SEI) Service Exception class mapped from wsdl:fault (if any) Async Reponse Bean derived from response wsdl:message (if any) JAXB generated value types (mapped Java classes from schema types) Syntax:

wsimport [options] <wsdl>

Options:

-d <directory>
Specify w here to place generated output files

-b <path>
Specify external JAX-W S or JAXB binding files or additional schema files (Each <file> must have its ow n -b)

-B <jaxbOption>
Pass this option to JAXB schema compiler.

-keep
Keep generated source code files. It is enabled w hen -s option.

-p
Specifying a target package via this command-line option, overrides any w sdl and schema binding customization for package name and the default package name algorithm defined in the specification.

-s <directory>
Specify w here to place generated source code files. -keep is turned on w ith this option.

-wsdllocation <location> @WebServiceClient.wsdlLocation value.


Multiple JAX-W S and JAXB binding files can be specified using -b option and they can be used to customize various things like package names, bean names, etc. Example:

wsimport -p stockquote http://java.boot.by/StockQuote?wsdl


This w ill generate the Java artifacts and compile them by importing the http://java.boot.by/StockQuote?wsdl

1.1.2. Use external and embedded <jaxws:package>, <jaxws:enableWrapperStyle>, <jaxws:class> customizations


External Binding Declaration External binding files are semantically equivalent to embedded binding declarations. W hen wsimport processes the W SDL document for w hich there is an external binding file, it internalizes the binding declarations defined in the external binding file on the nodes in the W SDL document they target using the wsdlLocation attribute. The embedded binding declarations can exist in a W SDL file and an external binding file targeting that W SDL, but wsimport may give an error if, upon embedding the binding declarations defined in the external binding files, the resulting W SDL document contains conflicting binding declarations. Embedded Binding Declarations Embedded binding declarations follow different rules compared to the binding declarations declared in the external binding file. Here are some important facts and rules as defined in the JAX-W S 2.0 specification: An embedded binding declaration is specified by using the jaxws:bindings element as a W SDL extension. W hen a jaxws:bindings element is used as a W SDL extension, it must not have a node attribute. The binding declaration must not have a child element w hose qualified name is jaxws:bindings. A binding declaration embedded in a W SDL can only affect the W SDL element it extends. Here's an example of embedded binding declarations in the W SDL:

<wsdl:portType name="AddNumbersImpl"> <!-- wsdl:portType customizations --> <jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"> <!-- rename the generated SEI from AddNumbersImpl to MathUtil --> <jaxws:class name="MathUtil"/> ... </jaxws:bindings> <wsdl:operation name="addNumber"> ...

converted by Web2PDFConvert.com

</wsdl:portType>

The above W SDL file excerpt show s the wsdl:portType customization. jaxws:bindings appears as extension element of portType. It customizes the class name of the generated service endpoint interface. W ithout this customization, or by default, the service endpoint interface class is named after the wsdl:portType name. The binding declaration jaxws:class customizes the generated class to be named MathUtil instead of AddNumberImpl. Package Customization By default wscompile generates W SDL artifacts in a package computed from the W SDL targetNamespace. For example, a W SDL file w ith the targetNamespace http://java.boot.by w ithout any package customization w ill be mapped to the by.boot.java package. To customize the default package mapping you w ould use a jaxws:package customization on the wsdl:definitions node or it can directly appear inside the top level bindings element. An important thing to note is that -p option on command-line wsimport tool ( package attribute on wsimport Ant task), overrides the jaxws:package customization, it also overrides the schema package customization specified using JAXB schema customization. For example:

<bindings xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdlLocation="http://localhost:8080/jaxws-external-customize/addnumbers?WSDL" xmlns="http://java.sun.com/xml/ns/jaxws"> <package name="by.boot.java"> <javadoc>Mathutil package</javadoc> </package> ... </bindings>

or:

<bindings xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdlLocation="http://localhost:8080/jaxws-external-customize/addnumbers?WSDL" xmlns="http://java.sun.com/xml/ns/jaxws"> <bindings node="wsdl:definitions"> <package name="by.boot.java"> <javadoc>Mathutil package</javadoc> </package> ... </bindings> </bindings>

Wrapper Style

wsimport by default applies w rapper style rules to the abstract operation defined in the wsdl:portType, and if an operation qualifies the Java method signature is generated accordingly. W rapper style Java method generation can be disabled by using jaxws:enableWrapperStyle. jaxws:enableWrapperStyle can appear on the toplevel bindings element (w ith @wsdlLocation attribute), it can also appear on the follow ing target nodes: wsdl:definitions: global scope, applies to all the wsdl:operations of all wsdl:portType attributes. wsdl:portType applies to all the wsdl:operations in the portType. wsdl:operation applies to only this wsdl:operation.
For example:

<bindings xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdlLocation="http://localhost:8080/jaxws-external-customize/addnumbers?WSDL" xmlns="http://java.sun.com/xml/ns/jaxws"> <!-- applies to wsdl:definitions node, that would mean the entire wsdl --> <enableWrapperStyle>true</enableWrapperStyle> <!-- wsdl:portType operation customization --> <bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']/wsdl:operation[@name='addNumbers']"> <!-- change java method name from addNumbers() to add() --> <enableWrapperStyle>false</enableWrapperStyle> ... </bindings> </bindings>

In the example above the w rapper style is disabled for the addNumbers operation in AddNumbersImpl portType. This is because wsimport processes this binding in the follow ing order: first wsdl:operation, then its parent wsdl:portType, and finally wsdl:definitions. Here wsdl:operation addNumbers has this customization disabled so this is w hat is applied by wsimport to generate a bare Java method signature. Class Customization The generated class for wsdl:portType, wsdl:fault, soap:headerfault, and wsdl:server can be customized using the jaxws:class binding declaration.

The Service Endpoint Interface Class

wscompile w ill generate the service endpoint interface class MathUtil instead of the default AddNumbersImpl in this example:

<!-- wsdl:portType customization --> <bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']"> <!-- change the generated SEI class --> <class name="MathUtil">

converted by Web2PDFConvert.com

<javadoc>Perform mathematical computations</javadoc> </class> ... </bindings>

The Exception Class

wsimport w ill generate the MathUtilException class instead of the default AddNumbersExeption in this example:

<!-- change the generated exception class name --> <bindings node="wsdl:definitions/wsdl:portType[@name='AddNumbersImpl']/wsdl:operation[@name='addNumbers']/wsdl:fault[@name='AddNumbersException']"> <class name="MathUtilException"> <javadoc>Exception generated during computation</javadoc> </class> </bindings>

The Service Class

wsimport w ill generate MathUtilService instead of the default AddNumbersService in this example:

<!-- wsdl:service customization --> <bindings node="wsdl:definitions/wsdl:service[@name='AddNumbersService']"> <!-- change the generated service class --> <class name="MathUtilService"> <javadoc>Service to perform mathematical computations</javadoc> </class> </bindings>

1.1.3. Use JAXB customizations to configure mapping.


Inline Customizations
Customizations to JAXB bindings made by means of inline binding declarations in an XML schema file take the form of <xsd:appinfo> elements embedded in schema <xsd:annotation> elements ( xsd: is the XML schema namespace prefix, as defined in W 3C XML Schema Part 1: Structures). The general form for inline customizations is show n below :

<xsd:annotation> <xsd:appinfo> . . binding declarations . . </xsd:appinfo> </xsd:annotation>

Customizations are applied at the location at w hich they are declared in the schema. For example, a declaration at the level of a particular element w ould apply to that element only. Note that the XML Schema namespace prefix must be used w ith the <annotation> and <appinfo> declaration tags. In the example above, xsd: is used as the namespace prefix, so the declarations are tagged <xsd:annotation> and <xsd:appinfo>.

External Binding Customization Files


Customizations to JAXB bindings made by means of an external file containing binding declarations take the general form show n below :

<jxb:bindings schemaLocation = "xsd:anyURI"> <jxb:bindings node = "xsd:string">* <binding declaration> <jxb:bindings> </jxb:bindings>

schemaLocation is a URI reference to the remote schema. node is an XPath 1.0 expression that identifies the schema node w ithin schemaLocation to w hich the given binding declaration is associated.
For example, the first schemaLocation/node declaration in a JAXB binding declarations file specifies the schema name and the root schema node:

<jxb:bindings schemaLocation="po.xsd" node="/xsd:schema">

A subsequent schemaLocation/node declaration, say for a simpleType element named ZipCodeType in the above schema, w ould take the form:

<jxb:bindings node="//xsd:simpleType[@name='ZipCodeType']">

Customization files containing binding declarations are passed to the JAXB Binding compiler, xjc, using the follow ing syntax:

xjc -b <file> <schema>

converted by Web2PDFConvert.com

w here <file> is the name of binding customization file, and <schema> is the name of the schema(s) you w ant to pass to the binding compiler. You can have a single binding file that contains customizations for multiple schemas, or you can break the customizations into multiple bindings files:

xjc schema1.xsd schema2.xsd schema3.xsd -b bindings123.xjb

xjc schema1.xsd schema2.xsd schema3.xsd -b bindings1.xjb -b bindings2.xjb -b bindings3.xjb


Note that the ordering of schema files and binding files on the command line does not matter, although each binding customization file must be preceded by its ow n -b sw itch on the command line.

1.1.4. Build the web service implementation using the above artifacts.
blah-blah

1.1.5. Access MessageContext.SERVLET_CONTEXT from the injected @WebServiceContext


javax.xml.ws.WebServiceContext
The javax.xml.ws.WebServiceContext interface makes it possible for an endpoint implementation object and potentially any other objects that share its execution context to access information pertaining to the request being served. The WebServiceContext is treated as an injectable resource that can be set at the time an endpoint is initialized. The WebServiceContext object w ill then use thread-local information to return the correct information regardless of how many threads are concurrently being used to serve requests addressed to the same endpoint object. In Java SE, the resource injection denoted by the WebServiceContext annotation is REQUIRED to take place only w hen the annotated class is an endpoint implementation class. The follow ing code show s a simple endpoint implementation class w hich requests the injection of its WebServiceContext:

@WebService public class Test { @Resource private WebServiceContext context; public String reverse(String inputString) { MessageContext mc = context.getMessageContext(); ServletContext servletContext = (ServletContext) mc.get(MessageContext.SERVLET_CONTEXT); ... } }
The @javax.annotation.Resource annotation defined by JSR-250 is used to request injection of the WebServiceContext. Then invoke the getMessageContext() method and w ork w ith the MessageContext object.

1.1.6. Configure deployment descriptors (web.xml, webservices.xml) for URL patterns, HTTP security, container authorization, caller authentication, and message protection. JAX-WS runtime may also be configured to perform message layer authentication and protection.
URL patterns The web.xml file contains information about the structure and external dependencies of w eb components in the module and describes how the components are used at run time. For Java API for XML-Based Web Services (JAX-W S) applications, you can customize the URL pattern in the web.xml file. W hen you package a JAX-W S application as a w eb service, the w eb service is contained w ithin a Web ARchive (W AR) file or a W AR module w ithin an enterprise archive (EAR) file. A JAX-W S enabled W AR file contains the follow ing items: A WEB-INF/web.xml file that describes configuration and deployment information for the w eb components that comprise a w eb application. Annotated classes that implement the w eb services contained in the application module including the service endpoint implementation class. JAXB classes. (Optional) Web Services Description Language (W SDL) documents that describe the w eb services contained in the application module. (Optional) XML schema files. (Optional) utility classes. (Optional) w eb service clients. The default URL pattern is defined by the @WebService.serviceName attribute that is contained in your w eb service implementation class. W hen the W SDL file that is associated w ith your service implementation class contains a single port definition, you can choose to use the default URL pattern or you can customize the URL pattern w ithin the web.xml file. W hen the W SDL file that is associated w ith your service implementation class contains multiple port definitions w ithin the same service definition, customized URL patterns are required. If you use the default URL pattern w hen the service implementation class contains multiple port definitions, then multiple service implementation classes are mapped to the same URL pattern w hich results in an error condition. You must edit the web.xml file and customize the URL patterns for each service definition. Each port maps to a w eb service implementation class and to its ow n custom URL pattern. By customizing the URL pattern in the web.xml file, you correct conflicting URL pattern definitions. 1. Determine if custom URL patterns are required or desired. Custom URL patterns are only required w hen the W SDL file for your JAX-W S w eb service contains multiple port definitions w ithin a single service. Otherw ise, you may optionally define custom URL patterns. 2. To customize the URL pattern for a service implementation class, edit the web.xml file and provide a <servlet> and corresponding <servlet-mapping> entry for each JAX-W S w eb service implementation class for w hich a custom URL pattern is desired. You must define the <url-pattern> value w ithin the <servlet-mapping> entry. The follow ing example illustrates the required URL pattern customizations w hen the W SDL file associated w ith the service implementation class has multiple port definitions. The follow ing excerpt is from a sample w eb service implementation classes:

package by.boot.java; @WebService(serviceName="EchoService", portName="SOAP11EchoServicePort") public class EchoServiceSOAP11{ ... }

package by.boot.java; @WebService(serviceName="EchoService", portName="SOAP12EchoServicePort") public class EchoServiceSOAP12{ ... }

converted by Web2PDFConvert.com

The follow ing excerpt is from the W SDL file associated w ith the EchoServiceSOAP11 w eb service implementation class. Each port in the W SDL file maps to a portName in the w eb service implementation class:

<wsdl:service name="EchoService"> <wsdl:port name="SOAP11EchoServicePort" tns:binding="..." > ... </wsdl:port> <wsdl:port name="SOAP12EchoServicePort" tns:binding="..." > ... </wsdl:port> </wsdl:service>

In this scenario, because there are multiple port definitions w ithin the W SDL file, you must customize the URL pattern by editing the web.xml file. Specify custom URL patterns for each service. The follow ing excerpt is from a sample web.xml file that demonstrates setting up a servlet:

<servlet> <servlet-name>by.boot.java.EchoServiceSOAP11</servlet-name> <servlet-class>by.boot.java.EchoServiceSOAP11</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>by.boot.java.EchoServiceSOAP11</servlet-name> <url-pattern>/EchoServiceSOAP11</url-pattern> </servlet-mapping> <servlet> <servlet-name>by.boot.java.EchoServiceSOAP12</servlet-name> <servlet-class>by.boot.java.EchoServiceSOAP12</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>by.boot.java.EchoServiceSOAP12</servlet-name> <url-pattern>/EchoServiceSOAP12</url-pattern> </servlet-mapping>

Basic Authentication with JAX-WS W hen a service that is constrained by HTTP basic authentication is requested, the server requests a user name and passw ord from the client and verifies that the user name and passw ord are valid by comparing them against a database of authorized users. Annotating the Service In this example, annotations are used to specify w hich users are authorized to access w hich methods of this service. In this simple example, the @RolesAllowed annotation is used to specify that users in the application role of basicUser are authorized access to the sayHello(String name) method. This application role must be linked to a group of users on the Application Server. The code snippet is as follow s:

import javax.jws.WebMethod; import javax.jws.WebService; import javax.annotation.security.RolesAllowed; @WebService() public class Hello { private String message = new String("Hello, "); @WebMethod() @RolesAllowed("basicUser") public String sayHello(String name) { return message + name + "."; } }
The @RolesAllowed annotation specifies that only users in the role of basicUser w ill be allow ed to access the sayHello(String name) method. A @RolesAllowed annotation implicitly declares a role that w ill be referenced in the application, therefore, no @DeclareRoles annotation is required. Adding Security Elements to the Deployment Descriptor To enable basic authentication for the service, add security elements to the application deployment descriptor, WEB-INF/web.xml. The security elements that need to be added to the deployment descriptor include the <security-constraint> and <login-config> elements:

<?xml version="1.0" encoding="UTF-8"?> <web-app> <listener> <listener-class> com.sun.xml.ws.transport.http.servlet.WSServletContextListener </listener-class> </listener> <servlet> <display-name>HelloService</display-name> <servlet-name>HelloService</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloService</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <security-constraint>

converted by Web2PDFConvert.com

<display-name>SecurityConstraint</display-name> <web-resource-collection> <web-resource-name>WRCollection</web-resource-name> <url-pattern>/hello</url-pattern> </web-resource-collection> <auth-constraint> <role-name>basicUser</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-constraint>BASIC</auth-constraint> <realm-name>file</realm-name> </login-config> </web-app>

Linking Roles to Groups The role of basicUser has been defined for this application, but there is no group of basicUser defined for the Application Server. To map the role that is defined for the application ( basicUser) to a group that is defined on the Application Server ( user), add a <security-role-mapping> element to the runtime deployment descriptor, WEB-INF/sun-web.xml, as show n below :

<?xml version="1.0" encoding="UTF-8"?> <sun-web-app error-url=""> <context-root>/helloservice</context-root> <class-loader delegate="true"/> <security-role-mapping> <role-name>basicUser</role-name> <group-name>user</group-name> </security-role-mapping> </sun-web-app>

Client Sample client against the secured w eb service:

import javax.xml.ws.WebServiceRef; import javax.xml.ws.BindingProvider; public class HelloClient { @WebServiceRef(wsdlLocation="http://localhost:8080/helloservice/hello?wsdl") static HelloService service; public static void main(String[] args) { try { Hello port = service.getHelloPort(); // Cast the proxy to a BindingProvider BindingProvider prov = (BindingProvider) port; prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "mikalai"); prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "secret"); String response = port.sayHello("Mikalai"); } catch(Exception e) { e.printStackTrace(); } } }
There is one tricky aspect to the client: the use of the wsimport utility to generate the JAX-W S artifacts. The problem is that the w eb service's W SDL is also secured and therefore requires authentication for access. There are w orkarounds, of course. One option is to generate the W SDL locally by using the wsgen utility on the SIB. Another option is to get the W SDL from a nonsecure version of the service. The locally saved W SDL and its XSD are then fed into wsimport to generate the artifacts. The client application HelloClient uses the BindingProvider constants as keys for the username and passw ord. JAX-W S runrime expects the lookup keys for the username and passw ord to be the strings:

javax.xml.ws.security.auth.username javax.xml.ws.security.auth.password
These are the values of the BindingProvider constant USERNAME_PROPERTY and the constant PASSWORD_PROPERTY, respectively.

1.1.7. Compile and package the web service into a WAR file
blah-blah

1.1.8. Deploy the web service into a Java EE servlet container


blah-blah
Prev Part I. Exam Objectives Up Home Next 1.2. Create a web service starting from a WSDL file using JAX-WS

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

1.2. Create a web service starting from a WSDL file using JAX-WS Chapter 1. Create an SOAP web service in a servlet container

Next

1.2. Create a web service starting from a WSDL file using JAX-WS
1.2.1. Use @WebService to indicate a service
You can use the @WebService and @WebMethod annotations on a service endpoint implementation to specify Java methods that you w ant to expose as Java API for XMLBased Web Services (JAX-W S) w eb services. JAX-W S technology enables the implementation of w eb services based on both the standard service endpoint interface and a Provider interface. W hen developing a JAX-W S Web service starting from existing Java classes, know n as the bottom-up approach, you must annotate the class w ith either the @WebService or @WebServiceProvider annotation to initially define the class as a w eb service. Using the Provider interface is the dynamic approach to defining your JAX-W S services. To use the Provider interface, your class must implement the javax.xml.ws.Provider interface, and contain the @WebServiceProvider annotation. The Provider interface has one method, the invoke method, w hich uses generics in the Java programming language to control both the input and output types w hen w orking w ith various messages or message payloads. To describe your w eb services using the service endpoint interface (SEI) approach, initially define a w eb service, annotate the Java class w ith the @WebService annotation. How ever, you can also selectively annotate the individual methods w ith @WebMethod annotation to control how these methods are exposed as w eb services operations.

@javax.jws.WebService marks a Java class as implementing a w eb service, or a Java interface as defining a w eb service interface:

@Retention(value=RetentionPolicy.RUNTIME) @Target({TYPE}) public @interface WebService { String name() default ""; String targetNamespace() default ""; String serviceName() default ""; String wsdlLocation() default ""; String endpointInterface() default ""; String portName() default ""; };
Table 1.1. @javax.jws.WebService
Member-Value Meaning The name of the web service. Used as the name of the wsdl:portType when mapped to WSDL 1.1. The XML namespace used for the WSDL and XML elements generated from this web service. The service name of the web service. Used as the name of the wsdl:service when mapped to WSDL 1.1. Not allowed on interfaces. Default The simple name of the Java class or interface. Implementation-defined, as described in JAX-RPC 1.1. Typically derived from the package containing the web service. The simple name of the Java class + "Service".

name targetNamespace

serviceName

wsdlLocation

The location of a pre-defined WSDL describing the service. The wsdlLocation is a URL (relative or absolute) that refers to a pre-existing WSDL file. The presence of a wsdlLocation value indicates that the service implementation bean is implementing a pre-defined WSDL contract. The JSR-181 tool MUST instead provide feedback if the service implementation bean is inconsistent with the portType and bindings declared in this WSDL. Note that a single WSDL file might contain multiple portTypes and multiple bindings. The annotations on the service implementation bean determine the specific portType and bindings that correspond to the web service. The complete name of the service endpoint interface defining the service's abstract web service contract. This annotation allows the developer to separate the interface contract from the implementation. If this annotation is present, the service endpoint interface is used to determine the abstract WSDL contract (portType and bindings). The service endpoint interface MAY include JSR-181 annotations to customize the mapping from Java to WSDL. The service implementation bean MAY implement the service endpoint interface, but is not REQUIRED to do so. Not allowed on interfaces.

None.

endpointInterface

None - the web service contract is generated from annotations on the service implementation bean. If a service endpoint interface is required by the target environment, it will be generated into an implementation-defined package with an implementation-defined name.

portName

The port name of the Web Service. Used as the name of the wsdl:port when mapped to WSDL 1.1. Not allowed on interfaces.

@WebService.name + "Port"

Example:

/** * Annotated Implementation Object */ @WebService( name = "EchoService", targetNamespace = "http://www.openuri.org/2004/04/HelloWorld"


converted by Web2PDFConvert.com

) public class EchoServiceImpl { @WebMethod public String echo(String input) { return input; } }
Use the follow ing best practices for defining w eb services: To define a basic w eb service, annotate the Java class w ith the @WebService annotation. To define your w eb services using an explicit SEI, add the @WebService annotation to a Java implementation class and explicitly reference a Java interface using the @WebService.endpointInterface attribute. To define your w eb services using an implicit SEI, add the @WebService annotation to a Java implementation class and do not define the @WebService.endpointInterface attribute. Provide a reference to a W SDL file in the @WebService.wsdlLocation attribute. By specifying a pre-defined W SDL file, performance is improved. Additionally, any discrepancies betw een the W SDL file and the annotations are reported to you by the runtime environment. W hen you use an explicit SEI, all public methods in the SEI and inherited classes are alw ays exposed. You only need to add @WebMethod annotations if you w ant to further customize the methods that are already exposed. If you define an implicit SEI, follow these rules to ensure that your methods are exposed consistently: Add an @WebService annotation to your implementation class and all its superclasses that contain methods that you w ant to expose. Adding an @WebService annotation to a class exposes all public methods in that class. If you w ant more granular control and expose only certain methods from a class that is annotated w ith the @WebService annotation, you can use the @WebMethod annotation on selected individual methods. The @WebMethod.exclude attribute is one of the criteria that is used to determine w hether a method is exposed as an operation. The default value for this attribute is false. To ensure that a method is exposed, annotate it w ith the @WebMethod annotation. If you w ant to make sure that a method is NOT exposed, annotate it w ith the @WebService(exclude=true) annotation.

1.2.2. Use @WebMethod, @WebMethod(exclude) to indicate service methods


@javax.jws.WebMethod customizes a method that is exposed as a w eb w ervice operation.

@Retention(value=RetentionPolicy.RUNTIME) @Target({METHOD}) public @interface WebMethod { String operationName() default ""; String action() default "" ; };
The @WebMethod annotation includes the follow ing member-value pairs: Table 1.2. @javax.jws.WebMethod
Member-Value Meaning Name of the wsdl:operation matching this method. The action for this operation. For SOAP bindings, this determines the value of the SOAPAction header. Marks a method to NOT be exposed as a web method. Used to stop an inherited method from being exposed as part of this web service. If this element is specified, other elements MUST NOT be specified for the @WebMethod. This member-value is not allowed on endpoint interfaces. Default The name of the Java method. ""

operationName action exclude

false

Java source:

@WebService public class MyWebService { @WebMethod(operationName = "echoString", action="urn:EchoString") public String echo(String input) { return input; } }
Resulting W SDL:

<definitions> <portType name="MyWebService"> <operation name="echoString"/> <input message="echoString"/> <output message="echoStringResponse"/> </operation> </portType>

converted by Web2PDFConvert.com

<binding name="PingServiceHttpSoap"> <operation name="echoString"> <soap:operation soapAction="urn:EchoString"/> </operation> </binding> </definitions>

NOTE: Beginning w ith Sun and HP JDK Version 1.6 containing JAX-W S tooling Version 2.1.6, the behavior of the JAX-W S runtime environment and tooling has changed how it interprets the JAX-W S specification regarding exposing methods as w eb services operations. W hen the w eb service does not specify a pre-existing W SDL file, the JAX-W S tooling behavior that generates a W SDL file has changed. This change does not affect w eb services that reference a W SDL file. The change in semantics might affect w eb services that do not reference a W SDL file or a SEI, and they rely on the JAX-W S runtime environment to create a W SDL file. Using the NEW interpretation, a method in an implicit SEI and its superclasses are only exposed under the follow ing conditions: The method has an @WebMethod or @WebMethod(exclude=false) annotation. The method has no @WebMethod annotations, but the containing class has an @WebService annotation. Using the LEGACY interpretation, a method in an implicit SEI and its superclasses are only exposed under the follow ing conditions: The method has an @WebMethod or @WebMethod(exclude=false) annotation and the containing class has an @WebService annotation. The method has no @WebMethod annotations, but the containing class has a @WebService annotation and no other methods have @WebMethod or @WebMethod(exclude=false) annotations on it. Example:

public class Base { @WebMethod(exclude=false) public void superMethod1(String s) {...} public String superMethod2(String s) {...} }

@WebService(targetNamespace="foo") public class BeanImpl extends Base { @WebMethod(exclude=false) public void method1(String s) {...} public String method2(String s) {...} }
Before JAX-W S 2.1.6, the only exposed method w ould be:

public void method1(String s) {...}


In JAX-W S 2.1.6 and later the follow ing methods w ill be exposed:

public void superMethod1(String s) {...} public void method1(String s) {...} public String method2(String s) {...}

1.2.3. Use @SOAPBinding to select doc/lit, doc/bare, rpc/lit style of web service
@javax.jws.soap.SOAPBinding specifies the mapping of the w eb service onto the SOAP message protocol. The SOAPBinding annotation has a target of TYPE and METHOD. The annotation may be placed on a method if and only if the SOAPBinding.style is DOCUMENT. Implementations MUST report an error if the SOAPBinding annotation is placed on a method w ith a SOAPBinding.style of RPC. Methods that do not have a SOAPBinding annotation accept the SOAPBinding behavior defined on
the type. The @SOAPBinding annotation includes the follow ing member-value pairs: Table 1.3. @javax.jws.soap.SOAPBinding
Member-Value Meaning Defines the encoding style for messages send to and from the web service. One of DOCUMENT or RPC. Defines the formatting style for messages sent to and from the web service. One of LITERAL or ENCODED. Determines whether method parameters represent the entire message body, or whether the parameters are elements wrapped inside a top-level element named after the operation. Default

style use parameterStyle

DOCUMENT LITERAL WRAPPED

@Retention(value=RetentionPolicy.RUNTIME) @Target({TYPE, METHOD})

converted by Web2PDFConvert.com

public @interface SOAPBinding { public enum Style { DOCUMENT, RPC }; public enum Use { LITERAL, ENCODED }; public enum ParameterStyle { BARE, WRAPPED } Style style() default Style.DOCUMENT; Use use() default Use.LITERAL; ParameterStyle parameterStyle() default ParameterStyle.WRAPPED; }
RPC/LITERAL Java source:

@WebService(targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample1") @SOAPBinding( style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL) public class ExampleService { @WebMethod public String concat(String first, String second, String third) { return first + second + third; } }
Resulting W SDL:

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.openuri.org/jsr181/SoapBindingExample1" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample1"> <message name="concat"> <part name="first" type="xs:string"/> <part name="second" type="xs:string"/> <part name="third" type="xs:string"/> </message> <message name="concatResponse"> <part name="return" type="xs:string"/> </message> <portType name="ExampleService"> <operation name="concat"> <input message="tns:concat"/> <output message="tns:concatResponse"/> </operation </portType> <binding name="ExampleServiceHttpSoap" type="ExampleService"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="concat"> <soap:operation soapAction="http://www.openuri.org/jsr181/SoapBindingExample1/concat" /> <input> <soap:body parts="first second third" use="literal"/> </input> <output> <soap:body parts="return" use="literal"/> </output> </operation> </binding> </definitions>

DOCUMENT/LITERAL/BARE Java source:

converted by Web2PDFConvert.com

@WebService(targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample2") @SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.BARE) public class DocBareService { @WebMethod( operationName="SubmitPO" ) public SubmitPOResponse submitPO(SubmitPORequest submitPORequest) { ... } }
Resulting W SDL:

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.openuri.org/jsr181/SoapBindingExample2" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample2"> <types> <s:schema elementFormDefault="qualified" targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample2"> <s:element name="SubmitPORequest"> . . . </s:element> <s:element name="SubmitPOResponse"> . . . </s:element> </s:schema> </types> <message name="SubmitPO"> <part name="parameters" element="tns:SubmitPORequest"/> </message> <message name="SubmitPOResponse"> <part name="parameters" element="tns:SubmitPOResponse"/> </message> <portType name="DocBareService"> <operation name="SubmitPO"> <input message="tns:SubmitPO"/> <output message="tns:SubmitPOResponse"/> </operation </portType> <binding name="DocBareServiceHttpSoap" type="ExampleService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="SubmitPO"> <soap:operation soapAction="http://www.openuri.org/jsr181/SoapBindingExample2/SubmitPO" /> <input> <soap:body parts="parameters" use="literal"/> </input> <output> <soap:body parts="parameters" use="literal"/> </output> </operation> </binding> </definitions>

DOCUMENT/LITERAL/WRAPPED Java source:

@WebService(targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample3") @SOAPBinding( style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED) public class DocWrappedService { @WebMethod(operationName = "SubmitPO") @WebResult(name="PurchaseOrderAck") public PurchaseOrderAck submitPO( @WebParam(name="PurchaseOrder") PurchaseOrder purchaseOrder) { ... } }

converted by Web2PDFConvert.com

Resulting W SDL:

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.openuri.org/jsr181/SoapBindingExample3" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample3"> <types> <s:schema elementFormDefault="qualified" targetNamespace="http://www.openuri.org/jsr181/SoapBindingExample3"> <s:element name="SubmitPO"> <complexType> <sequence> <element name="PurchaseOrder" type="tns:PurchaseOrder"/> . . . </sequence> </complexType> </s:element> <s:element name="SubmitPOResponse"> . . . </s:element> </s:schema> </types> <message name="SubmitPO"> <part name="parameters" element="tns:SubmitPO"/> </message> <message name="SubmitPOResponse"> <part name="parameters" element="tns:SubmitPOResponse"/> </message> <portType name="DocWrappedService"> <operation name="SubmitPO"> <input message="tns:SubmitPO"/> <output message="tns:SubmitPOResponse"/> </operation </portType> <binding name="ExampleServiceHttpSoap" type="ExampleService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="SubmitPO"> <soap:operation soapAction="http://www.openuri.org/jsr181/SoapBindingExample3/SubmitPO" /> <input> <soap:body parts="parameters" use="literal"/> </input> <output> <soap:body parts="parameters" use="literal"/> </output> </operation> </binding> </definitions>

1.2.4. Use @Oneway where the service doesn't have any response
The @javax.jws.Oneway annotation indicates that the given w eb method has only an input message and no output. Typically, a onew ay method returns the thread of control to the calling application prior to executing the actual business method. A JSR-181 processor is REQUIRED to report an error if an operation marked @Oneway has a return value, declares any checked exceptions or has any INOUT or OUT parameters.

@Retention(value=RetentionPolicy.RUNTIME) @Target({METHOD}) public @interface Oneway { };


Java source:

@WebService public class PingService { @WebMethod @Oneway public void ping() { ... } }
Resulting W SDL:

converted by Web2PDFConvert.com

<definitions> <message name="ping"/> ... <portType name="PingService"> <operation name="ping"> <input message="ping"/> </operation> </portType> </definitions>

1.2.5. Use @WebParam, and @WebResult to customize parameter and operation names
WebParam The @javax.jws.WebParam annotation customizes the mapping of an individual parameter to a w eb service message part and XML element. Table 1.4. @javax.jws.WebParam
Member-Value Meaning Name of the parameter. If the operation is rpc style and @WebParam.partName has not been specified, this is name of the wsdl:part representing the parameter. If the operation is document style or the parameter maps to a header, this is the local name of the XML element representing the parameter. A name MUST be specified if the operation is document style, the parameter style is BARE, and the mode is OUT or INOUT. Default

name

@WebMethod.operationName, if the operation is document style and the parameter style is BARE.
Otherwise, the default is argN, where N represents the index of the parameter in the method signature (starting at arg0).

partName

The name of the wsdl:part representing this parameter. @WebParam.name This is only used if the operation is rpc style or if the operation is document style and the parameter style is BARE. The XML namespace for the parameter. The empty namespace, if the operation is document style, the parameter style is WRAPPED, and the parameter does Only used if the operation is document style or the paramater not map to a header. maps to a header. Otherwise, the default is the targetNamespace for the If the target namespace is set to "", this represents the web service. empty namespace. The direction in which the parameter is flowing. One of IN, OUT, or INOUT. The OUT and INOUT modes may only be specified for parameter types that conform to the definition of Holder types. Parameters that are Holder types MUST be OUT or INOUT. If true, the parameter is pulled from a message header rather then the message body.

targetNamespace

mode

IN if not a Holder type. INOUT if a Holder type.

header

false

Java Source:

@WebService(targetNamespace="http://www.openuri.org/jsr181/WebParamExample") @SOAPBinding(style=SOAPBinding.Style.RPC) public class PingService { @WebMethod(operationName = "PingOneWay") @Oneway public void ping(PingDocument ping) { ... } @WebMethod(operationName = "PingTwoWay") public void ping( @WebParam(mode=WebParam.Mode.INOUT) PingDocumentHolder ping) { ... } @WebMethod(operationName = "SecurePing") @Oneway public void ping( PingDocument ping, @WebParam(header=true) SecurityHeader secHeader) { ... } }
Resulting W SDL:

converted by Web2PDFConvert.com

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.openuri.org/jsr181/WebParamExample" xmlns:wsdl="http://www.openuri.org/jsr181/WebParamExample" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://www.openuri.org/jsr181/WebParamExample"> <types> <s:schema elementFormDefault="qualified" targetNamespace="http://www.openuri.org/jsr181/WebParamExample"> <s:complexType name="PingDocument"> . . . </s:complexType> <s:complexType name="SecurityHeader"> . . . </s:complexType> <s:element name="SecurityHeader" type="SecurityHeader"/> </s:schema> </ types> <message name="PingOneWay"> <part name="arg0" type="tns:PingDocument"/> </message> <message name="PingTwoWay"> <part name="arg0" type="tns:PingDocument"/> </message> <message name="PingTwoWayResponse"> <part name="arg0" type="tns:PingDocument"/> </message> <message name="SecurePing"> <part name="arg0" type="tns:PingDocument"/> <part name="arg1" element="tns:SecurityHeader"/> </message> <portType name="PingService"> <operation name="PingOneWay"> <input message="tns:PingOneWay"/> </operation> <operation name="PingTwoWay"> <input message="tns:PingTwoWay"/> <output message="tns:PingTwoWayResponse"/> </operation> <operation name="SecurePing"> <input message="tns:SecurePing"/> </operation> </portType> <binding name="PingServiceHttpSoap" type="tns:PingService"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="PingOneWay"> <soap:operation soapAction="http://openuri.org/PingOneWay" /> <input> <soap:body parts="arg0" use="literal"/> </input> </operation> <operation name="PingTwoWay"> <soap:operation soapAction="http://openuri.org/PingTwoWay"/> <input> <soap:body parts="arg0" use="literal"/> </input> <output> <soap:body parts="arg0" use="literal"/> </output> </operation> <operation name="SecurePing"> <soap:operation soapAction="http://openuri.org/SecurePing"/> <input> <soap:body parts="arg0" use="literal"/> <soap:header message="SecurePing" part="arg1" use="literal"/> </input> </operation> </binding> </definitions>

converted by Web2PDFConvert.com

WebResult Use the @javax.jws.WebResult annotation to map to an existing wsdl:output or to customize how it's generated. Table 1.5. @javax.jws.WebResult
Member-Value Meaning Name of return value. If the operation is rpc style and @WebResult.partName has not been specified, this is the name of the wsdl:part representing the return value. If the operation is document style or the return value maps to a header, this is the local name of the XML element representing the return value. Default

name

@WebParam.operationName + "Response", if the


operation is document style and the parameter style is BARE. Otherwise, the default is "return".

partName

The name of the wsdl:part representing this return value. @WebResult.name This is only used if the operation is rpc style, or if the operation is document style and the parameter style is BARE. The XML namespace for the return value. Only used if the operation is document style or the return value maps to a header. If the target namespace is set to "", this represents the empty namespace. The empty namespace, if the operation is document style, the parameter style is WRAPPED, and the return value does not map to a header. Otherwise, the default is the targetNamespace for the web service.

targetNamespace

header

If true, the parameter is in the message header rather than the message body.

false

Java Source:

@WebService public class CustomerService { @WebMethod @WebResult(name="CustomerRecord") public CustomerRecord locateCustomer( @WebParam(name="FirstName") String firstName, @WebParam(name="LastName") String lastName, @WebParam(name="Address") USAddress addr) { ... } }
Resulting W SDL:

<definitions> <types> <complexType name="CustomerRecord"> ... </complexType> <complexType name="USAddress"> ... </complexType> <element name="locateCustomer"> <complexType> <sequence> <element name="FirstName" type="xs:string" /> <element name="LastName" type="xs:string" /> <element name="Address" type="USAddress"/> </sequence> </complexType> </element> <element name="locateCustomerResponse"> <complexType> <sequence> <element name="CustomerRecord" type="CustomerRecord"/> </sequence> </complexType> </element> </types> <message name="locateCustomer"> <part name="parameters" element="tns:locateCustomer"/> </message>

converted by Web2PDFConvert.com

<message name="locateCustomerResponse"> <part name="parameters" element="tns:locateCustomerResponse"/> </message> <portType name="CustomerService"> <operation name="locateCustomer"> <input message="tns:locateCustomer"/> <output message="tns:locateCustomerResponse"/> </operation> </portType> </definitions>

1.2.6. Use checked exceptions to indicate service specific faults.


blah-blah

1.2.7. Use wsgen tool to generate artifacts in Java EE5 (optional in Java EE6, as artifacts are generated at run time).
blah-blah

1.2.8. Configure deployment descriptors (web.xml, webservices.xml) for URL patterns, HTTP security, container authorization, caller authentication, and message protection. JAX-WS runtime may also be configured to perform message layer authentication and protection.
blah-blah

1.2.9. Compile and package the web service into a WAR file
blah-blah

1.2.10. Deploy the web service into a Java EE servlet container


blah-blah
Prev Chapter 1. Create an SOAP web service in a servlet container Up Home Next Chapter 2. Create a RESTful web service in a servlet container

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 2. Create a RESTful web service in a servlet container Part I. Exam Objectives

Next

Chapter 2. Create a RESTful web service in a servlet container 2.1. Create a web service using JAX-RS, refer to Jersey implementation for examples
2.1.1. Annotate a class with a @Path annotation to respond to URI templates.
blah-blah

2.1.2. Annotate the class's methods to respond to HTTP requests using the corresponding JAX-RS annotations (@GET, @POST, etc.).
blah-blah

2.1.3. Use the JAX-RS @Consumes and @Produces annotations to specify the input and output formats for the RESTful web service.
blah-blah

2.1.4. Use @PathParam, @QueryParam, @MatrixParam and @HeaderParam to extract request data.
@javax.ws.rs.PathParam

@PathParam allow s you to inject the value of named URI path parameters that w ere defined in @Path expressions:

@Path("/employee") public class EmployeeResource { @Path("{id}") @GET public Employee getEmployee(@PathParam("id") int id) { ... } }
In the example above, w e w ant to route HTTP GET requests to the relative URI pattern /employee/{id}. The getEmployee(...) method extracts an Employee ID from the URI using @PathParam annotation. The value of the @PathParam annotation, "id", matches the path parameter, {id}, that w as defined in the @Path expression of getEmployee(...). W hile {id} represents a string segment in the request's URI, JAX-RS runtime automatically converts the value to an int before it invokes the getEmployee(...) method. If the URI path parameter cannot be converted to an integer, the request is considered a client error and the client w ill receive an HTTP 404, "Not Found" status code from the server. @javax.ws.rs.QueryParam The @QueryParam annotation allow s you to inject individual URI query parameters into your Java parameters. For example, let's say you w anted to query a employee database and retrieve a subset of all employees in the database. Your URI might look like this:

GET /employees?start=30&size=10
The start query parameter represents the employee index you w ant to start w ith and the size query parameter represents how many employees you w ant returned. The JAX-RS service that implemented this might look like this:

@Path("/employees") public class EmployeeResource { @GET @Produces("application/xml") public String getEmployees(@QueryParam("start") int start, @QueryParam("size") int size) { ... } }
The @QueryParam annotation w as used to inject the URI query parameters "start" and "size" into the Java parameters start and size. As w ith other annotation injection, JAX-RS runtime automatically converts the query parameter's string into an integer. @javax.ws.rs.MatrixParam The @MatrixParam annotation extracts information from URL path segments. @javax.ws.rs.HeaderParam The @HeaderParam annotation is used to inject HTTP request header values. For example, w hat if your application w as interested in the w eb page that referred to or linked to your w eb service? You could access the HTTP Referer header using the @HeaderParam annotation:

@Path("/myresource") public class MyResource { @GET public String getData(@HeaderParam("Referer") String referer) { ... } }
converted by Web2PDFConvert.com

The @HeaderParam annotation is pulling the Referer header directly from the HTTP request and injecting it into the referer method parameter.

2.1.5. Use the UriInfo and UriBuilder to create URIs that refer to resources in the service.
A very important aspects of REST is hyperlinks, URIs, in representations that clients can use to transition the w eb service to new application states (this is otherw ise know n as "hypermedia as the engine of application state"). HTML forms present a good example of this in practice. Using Java API for RESTful Web Services (JAX-RS), you can use the UriInfo object to access request headers. The UriInfo object provides methods to enable you to find or build URI information of a request. Using an injected UriInfo object by the JAX-RS runtime environment, the relative and absolute uniform resource identifier (URI) information is know n and available for modification. The @javax.ws.rs.core.Context annotation indicates that a context object is injected. The javax.ws.rs.core.UriInfo interface is the interface of the object that you w ant to inject. You can use the UriInfo object to build absolute and relative URLs using the UriBuilder class. If a resource method signature can be modified, add the @javax.ws.rs.core.Context javax.ws.rs.core.UriInfo parameter to the method. W hen the resource method is invoked, the JAX-RS runtime environment passes an object that implements the UriInfo object; for example:

@Path("/resource") public class RootResource { @GET public String getResource(@Context UriInfo uriInfo) { // Client used this URI to reach this resource method return uriInfo.getAbsolutePath().toASCIIString(); } }
If a resource method signature cannot be modified and the class is a root resource, add the @javax.ws.rs.core.Context javax.ws.rs.core.UriInfo field. W hen the resource is instantiated for a request, an object that implements UriInfo is injected; for example:

@Path("/contextexample") public class RootResource { @Context UriInfo uriInfo; @GET public String getResource() { // Client used this URI to reach this resource method return uriInfo.getAbsolutePath().toASCIIString(); } }
Building URIs and building them safely is not easy w ith java.net.URI, w hich is w hy JAX-RS has the UriBuilder class that makes it simple and easy to build URIs safely.

UriBuilder can be used to build new URIs or build from existing URIs. For resource classes it is more than likely that URIs w ill be built from the base URI the w eb service is deployed at or from the request URI. The class UriInfo provides such information (in addition to further information, see next section).
The follow ing example show s URI building w ith UriInfo and UriBuilder:

@Path("/users/") public class UsersResource { @Context UriInfo uriInfo; ... @GET @Produces("application/json") public JSONArray getUsersAsJsonArray() { JSONArray uriArray = new JSONArray(); for (UserEntity userEntity : getUsers()) { UriBuilder ub = uriInfo.getAbsolutePathBuilder(); URI userUri = ub .path(userEntity.getUserid()) .build(); uriArray.put(userUri.toASCIIString()); } return uriArray; } }
An instance of UriInfo can be injected into a class field or method parameter using the @Context annotation. UriInfo provides both static and dynamic, per-request information, about the components of a request URI. E.g. the follow ing w ould return the names of any query parameters in a request:

@GET @Produces{"text/plain"}
converted by Web2PDFConvert.com

public String listQueryParamNames(@Context UriInfo info) { StringBuilder buf = new StringBuilder(); for (String param: info.getQueryParameters().keySet()) { buf.append(param); buf.append("\n"); } return buf.toString(); }
UriInfo can be used to obtain URIs and associated UriBuilder instances for the follow ing URIs: the base URI the application is deployed at; the request URI; and the
absolute path URI, w hich is the request URI minus any query components. The getUsersAsJsonArray method constructs a JSONArrray w here each element is a URI identifying a specific user resource. The URI is built from the absolute path of the request URI by calling uriInfo.getAbsolutePathBuilder(). A new path segment is added, w hich is the user ID, and then the URI is built. Notice that it is not necessary to w orry about the inclusion of ' /' characters or that the user ID may contain characters that need to be percent encoded. UriBuilder takes care of such details.

UriBuilder can be used to build/replace query or matrix parameters. URI templates can also be declared, for example the follow ing w ill build the URI:

http://localhost/segment?name=value

UriBuilder.fromUri("http://localhost/"). path("{a}"). queryParam("name", "{value}"). build("segment", "value");

2.1.6. Use ResponseBuilder to create response with customized status and additional metadata.
The HTTP specification defines w hat HTTP response codes should be on a successful request. For example, GET should return 200, OK and PUT should return 201, CREATED. You can expect JAX-RS to return the same default response codes. Sometimes, how ever, you need to specify your ow n response codes, or simply to add specific headers or cookies to your HTTP response. JAX-RS provides a Response class for this:

@Path("/orders") public class OrderEntryService { @GET @Path("{id}") public Response getOrder(@PathParm("id") int orderId) { Order order = OrderDAO.get(orderId); ResponseBuilder builder = Response.ok(order); Date expirationDate = new Date(System.currentTimeMillis() + 3000); // 3 secs builder.expires(expirationDate); return builder.build(); } }
In this example, w e still w ant to return a JAXB object w ith a 200 status code, but w e w ant to add an Expires header to the response. You use the ResponseBuilder class to build up the response, and ResponseBuilder.build() to create the final Response instance.

2.1.7. Implement a MessageBodyReader and MessageBodyWriter to add support for custom request and response data types
Java API for RESTful Web Services (JAX-RS) enables developers to add a custom entity provider to the application. Use custom entity providers w hen you w ant to use Java types to represent incoming request message bodies as w ell as represent outgoing response message bodies. By adding a custom entity provider, you can deserialize custom Java types from message bodies and serialize any media type as message bodies. A custom entity provider is created by annotating a class w ith a javax.ws.rs.ext.Provider annotation. The class must implement the javax.ws.rs.ext.MessageBodyReader interface or the javax.ws.rs.ext.MessageBodyWriter interface, or both. You must add the provider class to the list of classes returned in the javax.ws.rs.core.Application subclass getClasses() method. The MessageBodyReader interface represents a contract for a provider that supports the conversion of a stream to a Java type. To add a MessageBodyReader implementation, annotate the implementation class w ith @Provider. A MessageBodyReader implementation may be annotated w ith @Consumes to restrict the media types for w hich it w ill be considered suitable:

package javax.ws.rs.ext; import import import import import import import java.io.IOException; java.io.InputStream; java.lang.annotation.Annotation; java.lang.reflect.Type; javax.ws.rs.WebApplicationException; javax.ws.rs.core.MediaType; javax.ws.rs.core.MultivaluedMap;

public interface MessageBodyReader<T extends Object> { public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType); public T readFrom(Class<T> type,

converted by Web2PDFConvert.com

Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException; }

The MessageBodyWriter interface represents a contract for a provider that supports the conversion of a Java type to a stream. To add a MessageBodyWriter implementation, annotate the implementation class w ith @Provider. A MessageBodyWriter implementation may be annotated w ith Produces to restrict the media types for w hich it w ill be considered suitable:

package javax.ws.rs.ext; import import import import import import import java.io.IOException; java.io.OutputStream; java.lang.annotation.Annotation; java.lang.reflect.Type; javax.ws.rs.WebApplicationException; javax.ws.rs.core.MediaType; javax.ws.rs.core.MultivaluedMap;

public interface MessageBodyWriter<T extends Object> { public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType); public long getSize(T t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType); public void writeTo(T t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException; }

1. Create a new Java class that is your custom entity provider. In this procedure, the example code creates a reader and a w riter for by.boot.java.Order types so that you can use the by.boot.java.Order type as an incoming request entity parameter and as a return type to contain the response entity:

public class OrderEntityProvider { }


2. Add the @javax.ws.rs.ext.Provider annotation. Adding this annotation indicates to the JAX-RS runtime environment that this class is a JAX-RS provider. If this Provider annotation is not specified, the runtime environment does not detect that the class is a custom provider:

@javax.ws.rs.ext.Provider public class OrderEntityProvider { }


3. [optional] Add a @javax.ws.rs.Consumes and/or @javax.ws.rs.Produces annotation if you w ant to limit the media types that the entity provider supports. In the follow ing code snippet, the provider is only invoked w hen the incoming Content-Type or outgoing Content-Type is application/json:

@javax.ws.rs.ext.Provider @javax.ws.rs.Consumes("application/json") @javax.ws.rs.Produces("application/json") public class OrderEntityProvider { }


4. Implement javax.ws.rs.ext.MessageBodyReader<T> if the entity provider needs to deserialize a message body. You can use the generic type <T> to limit the types supported by the entity provider. By defining the message body reader as javax.ws.rs.ext.MessageBodyReader<by.boot.java.Order>, the JAX-RS runtime environment know s that only by.boot.java.Order objects can be produced:

converted by Web2PDFConvert.com

@javax.ws.rs.ext.Provider @javax.ws.rs.Consumes("application/json") @javax.ws.rs.Produces("application/json") public class OrderEntityProvider implements MessageBodyReader<by.boot.java.Order> { public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return by.boot.java.Order.class == type; } public by.boot.java.Order readFrom(Class<by.boot.java.Order> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { // This code reads from the entityStream and constructs the object. by.boot.java.Order retObj = by.boot.java.Order.parse(entityStream); return retObj; } }

If an entity provider needs to support a complex set of types, consider implementing javax.ws.rs.ext.MessageBodyReader<Object>. 5. Implement javax.ws.rs.ext.MessageBodyWriter<T> if the entity provider needs to serialize a message body. You can implement the MessageBodyReader<T> and MessageBodyWriter<T> interfaces in the same Java class. In the follow ing code snippet, only the MessageBodyWriter implementation is show n:

@javax.ws.rs.ext.Provider public class OrderEntityProvider implements MessageBodyWriter<by.boot.java.Order> { public long getSize(by.boot.java.Order t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { // Return -1 if the content length cannot be determined return -1; } public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return by.boot.java.Order.class == type; } public void writeTo(by.boot.java.Order t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { entityStream.write(t.getBytes()); } }

6. Add the custom entity provider to the javax.ws.rs.core.Application subclass and add the provider to the set of classes returned from the getClasses() method. You can add multiple custom entity providers to the set of classes returned:

public class MyApplication extends javax.ws.rs.core.Application { public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<Class<?>>(); classes.add(OrderEntityProvider.class); return classes; } }

2.1.8. Implement ExceptionMapper to map a custom Exception to a response.


JAX-RS has a RuntimeException class, WebApplicationException, that allow s you to abort your JAX-RS service method. It can take an HTTP status code or even a Response object as one of its constructor parameters. For example:
converted by Web2PDFConvert.com

Response object as one of its constructor parameters. For example:

@Path("/orders") public class OrderEntryService { @GET @Path("{id}") @Produces("application/xml") public Order getOrder(@PathParm("id") int orderId) { Order order = OrderDAO.get(orderId); if (order == null) { ResponseBuilder builder = Response.status(Status.NOT_FOUND); builder.type("text/html"); builder.entity("<h3>Order Not Found</h3>"); throw new WebApplicationException(builder.build(); } return order; } }

In this example, if the order is null, send a HTTP response code of NOT_FOUND w ith a HTML encoded error message. Beyond WebApplicationException, you can map non-JAX-RS exceptions that might be throw n by your application to a Response object by registering implementations of the ExceptionMapper class:

public interface ExceptionMapper<E extends Throwable> { Response toResponse(E exception); }

For example, lets say w e w ere using JPA to locate our Order objects. We could map javax.persistence.EntityNotFoundException to return a NOT_FOUND status code:

@Provider public class EntityNotFoundMapper implements ExceptionMapper<EntityNotFoundException> { Response toResponse(EntityNotFoundException exception) { return Response.status(Status.NOT_FOUND); } }

or

@Provider public class EntityNotFoundMapper implements ExceptionMapper<EntityNotFoundException> { Response toResponse(EntityNotFoundException exception) { return Response.status(Status.NOT_FOUND). entity(exception.getMessage()). type("text/plain"). build(); } }

The above class is annotated w ith @Provider, this declares that the class is of interest to the JAX-RS runtime. Such a class should be added to the set of classes of the Application instance that is configured. W hen an application throw s an EntityNotFoundException the toResponse method of the EntityNotFoundMapper instance w ill be invoked.

2.1.9. Use Request to add support for HTTP preconditions.


blah-blah

2.1.10. Implement the functionality of the JAX-RS resource's methods.


blah-blah

2.1.11. Use @Path on a method to define a subresource.


Methods of a resource class that are annotated w ith @Path are either sub-resource methods or sub-resource locators. Sub-resource methods handle an HTTP request directly w hilst sub-resource locators return an object that w ill handle an HTTP request. The presence or absence of a request method designator (e.g. @GET) differentiates betw een the tw o: Request method designator ( @GET, @POST) presents: Such methods, know n as sub-resource methods, are treated like a normal resource method except the method is only invoked for request URIs that match a URI template created by concatenating the URI template of the resource class w ith the URI template of the method. Example:

@Path("widgets")
converted by Web2PDFConvert.com

public class WidgetsResource { @GET @Path("offers") public WidgetList getDiscounted() {...} }


In the above a GET request for the widgets/offers resource is handled directly by the getDiscounted() sub-resource method of the resource class WidgetsResource. Request method designator ( @GET, @POST) absent: Such methods, know n as sub-resource locators, are used to dynamically resolve the object that w ill handle the request. Any returned object is treated as a resource class instance and used to either handle the request or to further resolve the object that w ill handle the request. An implementation MUST dynamically determine the class of object returned rather than relying on the static sub-resource locator return type since the returned instance may be a subclass of the declared type w ith potentially different annotations. Sub-resource locators may have all the same parameters as a normal resource method except that they MUST NOT have an entity parameter. Example:

@Path("widgets") public class WidgetsResource { @Path("{id}") public WidgetSubResource findWidget(@PathParam("id") String id) { return new WidgetSubResource(id); } }

public class WidgetSubResource { public WidgetSubResource(String id) {...} @GET public Widget getDetails() {...} }
In the above a GET request for widgets/xxx is handled by the getDetails() method of the WidgetSubResource resource class.

2.1.12. Configure deployment descriptor (web.xml) for base URL pattern, HTTP security (via security-constraints in web.xml)
blah-blah

2.1.13. Compile and package


blah-blah

2.1.14. Deploy the web service in a Java EE servlet container


blah-blah
Prev 1.2. Create a web service starting from a WSDL file using JAX-WS Up Home Next Chapter 3. Create a SOAP based web service implemented by an EJB component

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 3. Create a SOAP based web service implemented by an EJB component Part I. Exam Objectives

Next

Chapter 3. Create a SOAP based web service implemented by an EJB component 3.1. Create a web service starting from a WSDL file using JAX-WS
3.1.1. Use wsimport tool to generate artifacts and use customization files for wsimports if needed
blah-blah

3.1.2. Create an EJB web service implementations using annotations (@Stateless or @Singleton)
blah-blah

3.1.3. Configure deployment descriptors (ejb-jar.xml, webservices.xml) for transactions, etc.


blah-blah

3.1.4. Configure container role based access control via method-permissions in ejb-jar.xml or via access control annotations on EJB.
blah-blah

3.1.5. Configure caller authentication and message protection; either by Servlet Container via web.xml, and/or by JAX-WS message processing runtime.
blah-blah

3.1.6. Compile and package the web service into a EAR/WAR file (Java EE 6 - WAR can also have EJBs).
blah-blah

3.1.7. Deploy the web service into a Java EE container.


blah-blah
Prev Chapter 2. Create a RESTful web service in a servlet container Up Home Next 3.2. Create a web service starting from a Java source using JAX-WS

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

3.2. Create a web service starting from a Java source using JAX-WS Chapter 3. Create a SOAP based web service implemented by an EJB component

Next

3.2. Create a web service starting from a Java source using JAX-WS
3.2.1. Use wsgen tool to generate artifacts in Java EE5 from EJB classes (optional in Java EE 6 - as artifacts are generated at run time).
blah-blah

3.2.2. Configure deployment descriptors (ejb-jar.xml, webservices.xml) for transactions, etc.


blah-blah

3.2.3. Configure container role based access control via method-permissions in ejb-jar.xml or via access control annotations on EJB.
blah-blah

3.2.4. Configure caller authentication and message protection; either by Servlet Container via web.xml, and/or by JAX-WS message processing runtime.
blah-blah

3.2.5. Compile and package the web service into a WAR/EAR file.
blah-blah

3.2.6. Deploy the web service into a Java EE container.


blah-blah
Prev Chapter 3. Create a SOAP based web service implemented by an EJB component Up Home Next Chapter 4. Create a RESTful web service implemented by an EJB component

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 4. Create a RESTful web service implemented by an EJB component Part I. Exam Objectives

Next

Chapter 4. Create a RESTful web service implemented by an EJB component 4.1. Create a web service using JAX-RS from EJB classes.
A root resource class is anchored in URI space using the @Path annotation. The value of the annotation is a relative URI path template w hose base URI is provided by the deployment context. The follow ing code example is a very simple example of a root resource class using JAX-RS annotations:

import javax.ws.rs.GET; import javax.ws.rs.Produces; import javax.ws.rs.Path; // The Java class will be hosted at the URI path "/helloworld" @Path("/helloworld") public class HelloWorldResource { // The Java method will process HTTP GET requests @GET // The Java method will produce content identified by the MIME Media // type "text/plain" @Produces("text/plain") public String getClichedMessage() { // Return some cliched textual content return "Hello World"; } }

4.1.1. Annotate an enterprise bean class with a @Path annotation to respond to URL patterns.
@Target(value={TYPE,METHOD}) @Retention(value=RUNTIME) public @interface Path
Identifies the URI path that a resource class or class method w ill serve requests for. Paths are relative. For an annotated class the base URI is the application path. For an annotated method the base URI is the effective URI of the containing class. For the purposes of absolutizing a path against the base URI , a leading ' /' in a path is ignored and base URIs are treated as if they ended in ' /'. E.g.:

@Path("widgets") public class WidgetsResource { @GET String getList() {...} @GET @Path("{id}") String getWidget(@PathParam("id") String id) {...} }
In the above, if the application path is catalogue and the application is deployed at http://example.com/, then GET requests for http://example.com/catalogue/widgets w ill be handled by the getList() method w hile requests for http://example.com/catalogue/widgets/nnn (w here nnn is some value) w ill be handled by the getWidget() method. The same w ould apply if the value of either @Path annotation started w ith ' /'. Session beans (Stateless or Singleton) can be implemented as JAX-RS resource or provider classes. EJB 3.1 and JAX-RS w ork very w ell together thanks to JAX-RS flexibility in handling many kinds of resource classes, the EJB 3.1 no-interface view , and the ability to package enterprise beans directly in a .war:

import javax.ejb.*; import javax.ws.rs.*; @Path("name") @Stateless public class NameService { @EJB private NameBean nameBean; @GET @Produces("text/plain") public String getHtml() { return "Hello " + nameBean.getName(); } @PUT @Consumes("text/plain") public void put(String content) { nameBean.setName(content); } }
converted by Web2PDFConvert.com

The @Path annotation's value is a relative URI path. In the HelloWorldResource example above, the Java class w ill be hosted at the URI path /helloworld. This is an extremely simple use of the @Path annotation. W hat makes JAX-RS so useful is that you can embed variables in the URIs. URI path templates are URIs w ith variables embedded w ithin the URI syntax. These variables are substituted at runtime in order for a resource to respond to a request based on the substituted URI. Variables are denoted by curly braces. For example, look at the follow ing @Path annotation:

@Path("/users/{username}")
In this type of example, a user w ill be prompted to enter their name, and then a w eb service configured to respond to requests to this URI path template w ill respond. For example, if the user entered their username as "Mikalai", the w eb service w ill respond to the follow ing URL:

http://example.com/users/Mikalai
To obtain the value of the username variable the @PathParam may be used on method parameter of a request method, for example:

@Path("/users/{username}") public class UserResource { @GET @Produces("text/xml") public String getUser(@PathParam("username") String userName) { ... } }
If it is required that a user name must only consist of low er and upper case alpha-numeric characters then it is possible to declare a particular regular expression, w hich overrides the default regular expression, "[^/]+?", for example:

@Path("users/{username: [a-zA-Z][a-zA-Z_0-9]*}")
In this type of example the username variable w ill only match user names that begin w ith one upper or low er case letter and zero or more alpha numeric characters and the underscore character. If a user name does not match that a 404 (Not Found) response w ill occur. A @Path value may or may not begin w ith a ' /', it makes no difference. Likew ise, by default, a @Path value may or may not end in a ' /', it makes no difference, and thus request URLs that end or do not end in a ' /' w ill both be matched.

4.1.2. Annotate the class's methods to respond to HTTP requests using the corresponding JAX-RS annotations (@GET, @POST, etc.).
JAX-RS defines common HTTP methods using annotations: @GET, @POST, @PUT, @DELETE, @HEAD, and @OPTIONS. Only public methods may be exposed as resource methods. Listing below show s a customer resource exposing CRUD methods. Note that the createCustomer and updateCustomer methods take an InputStream as a parameter w hich represents the HTTP request body:

@Path("/customers") public class CustomerResource { @GET public List<Customer> getListOfCustomers() { // ... } @POST @Consumes(MediaType.APPLICATION_XML) public Response createCustomer(InputStream is) { // ... } @PUT @Path("{customerId}") @Consumes(MediaType.APPLICATION_XML) public Response updateCustomer(@PathParam("customerId") String customerId, InputStream is) { // ... } @DELETE @Path("{customerId}") public void deleteCustomer(@PathParam("customerId") String customerId) { // ... } }

4.1.3. Use the JAX-RS @Produces and @Consumes annotations to specify the input and output resources for the RESTful web service.
@Produces The @Produces annotation is used to specify the MIME media types of representations a resource can produce and send back to the client. In this example, the Java method w ill produce representations identified by the MIME media type "text/plain".

converted by Web2PDFConvert.com

@Produces can be applied at both the class and method levels. Here's an example:

@Path("/myResource") @Produces("text/plain") public class SomeResource { @GET public String doGetAsPlainText() { ... } @GET @Produces("text/html") public String doGetAsHtml() { ... } }
The doGetAsPlainText method defaults to the MIME type of the @Produces annotation at the class level. The doGetAsHtml method's @Produces annotation overrides the class-level @Produces setting, and specifies that the method can produce HTML rather than plain text. If a resource class is capable of producing more that one MIME media type then the resource method chosen w ill correspond to the most acceptable media type as declared by the client. More specifically the Accept header of the HTTP request declared w hat is most acceptable. For example if the Accept header is:

Accept: text/plain
then the doGetAsPlainText method w ill be invoked. Alternatively if the Accept header is:

Accept: text/plain; q=0.9, text/html


w hich declares that the client can accept media types of "text/plain" and "text/html" but prefers the latter, then the doGetAsHtml method w ill be invoked. More than one media type may be declared in the same @Produces declaration, for example:

@GET @Produces({"application/xml", "application/json"}) public String doGetAsXmlOrJson() { ... }


The doGetAsXmlOrJson method w ill get invoked if either of the media types "application/xml" and "application/json" are acceptable. If both are equally acceptable then the former w ill be chosen because it occurs first. The examples above refer explicitly to MIME media types for clarity. It is possible to refer to constant values, w hich may reduce typographical errors, see the constant field values of MediaType:

APPLICATION_ATOM_XML APPLICATION_FORM_URLENCODED APPLICATION_JSON APPLICATION_OCTET_STREAM APPLICATION_SVG_XML APPLICATION_XHTML_XML APPLICATION_XML MULTIPART_FORM_DATA TEXT_HTML TEXT_PLAIN TEXT_XML WILDCARD
@Consumes

"application/atom+xml" "application/x-www-form-urlencoded" "application/json" "application/octet-stream" "application/svg+xml" "application/xhtml+xml" "application/xml" "multipart/form-data" "text/html" "text/plain" "text/xml" "*/*"

The @Consumes annotation is used to specify the MIME media types of representations a resource can consume that w ere sent by the client. The above example can be modified to set the cliched message as follow s:

@POST @Consumes("text/plain") public void postClichedMessage(String message) { // Store the message }


In this example, the Java method w ill consume representations identified by the MIME media type "text/plain". Notice that the resource method returns void. This means no representation is returned and response w ith a status code of 204 (No Content) w ill be returned.

@Consumes can be applied at both the class and method levels and more than one media type may be declared in the same @Consumes declaration.
JAX-RS standard entity parameter types JAX-RS requires certain parameters to be supported for virtually any content type. The follow ing table lists the supported content types:

converted by Web2PDFConvert.com

Table 4.1. JAX-RS Standard Entity Parameter Types


Java Type Content Type Supported

java.lang.String byte[] java.io.InputStream java.io.Reader java.io.File javax.activation.DataSource javax.xml.transform.Source javax.xml.bind.JAXBElement and JAXB classes

*/* */* */* */* */* */* text/xml, application/xml, application/*+xml text/xml, application/xml, application/*+xml

javax.ws.rs.core.MultivaluedMap<String, application/x-www-formString> urlencoded javax.ws.rs.core.StreamingOutput (as a


writer only)

*/*

Developers can use the previous Java types as entity parameters for requests and responses:

@Path("/example") public class RootResource { @GET @Produces("text/xml") public Response getInfo() { ... } @POST @Consumes("application/json") @Produces("application/json") public StreamingOutput createItem(InputStream requestBodyStream) { /* read the requestBodyStream like a normal input stream */ ... } }

4.1.4. Implement the functionality of the JAX-WS resource's methods.


Extracting Request Parameters Parameters of a resource method may be annotated w ith parameter-based annotations to extract information from a request. The follow ing example presents the use @PathParam to extract a path parameter ( 98342) from the path component of the request URL ( http://java.boot.by/customers/98342) that matched the path declared in @Path:

@Path("/customers") public class CustomerResource { @GET public Customer getCustomer(@PathParam("customerId") customerId) { // ... } }
The @QueryParam annotation extracts the value of a URI query parameter. For example, the follow ing code allow s you to extract the ZIP code parameter ( 220119) out of the http://java.boot.by/customers?zip=220119 URI:

@Path("/customers") public class CustomerResource { @GET public Customer getCustomerByZipCode(@QueryParam("zip") Long zip) { // ... } }
W ith all parameters annotations, you can add a @DefaultValue annotation to define the default value for a parameter you are expecting. The default value is used if the corresponding metadata is not present in the request. In the follow ing code, if the query parameter age is not in the request, the default value 50 is set:

@Path("/customers") public class CustomerResource { @GET public Response getCustomers(@DefaultValue("50") @QueryParam("age") int age) { // ...

converted by Web2PDFConvert.com

} }
If the @DefaultValue is not used on conjuction w ith @QueryParam and the query parameter is not present in the request then value w ill be an empty collection for List, Set or SortedSet, null for other object types, and the Java-defined default for primitive types. The @PathParam and the other parameter-based annotations, @MatrixParam, @HeaderParam, @CookieParam and @FormParam obey the same rules as @QueryParam.

@MatrixParam extracts information from URL path segments (; is used as a delimiter instead of ?). For example, you w ill be able to extract the author's name ( Mikalai) out of this URL: http://java.boot.by/products/books;author=Mikalai. @HeaderParam extracts information from the HTTP headers. @CookieParam extracts information from the cookies declared in cookie related HTTP headers. @FormParam is slightly special because it extracts information from a request representation that is of the MIME media type "application/x-www-form-urlencoded" and
conforms to the encoding specified by HTML forms. This parameter is very useful for extracting information that is POSTed by HTML forms, for example the follow ing extracts the form parameter named "name" from the POSTed form data:

@POST @Consumes("application/x-www-form-urlencoded") public void post(@FormParam("name") String name) { // Store the message }
If it is necessary to obtain a general map of parameter name to values then, for query and path parameters it is possible to do the follow ing:

@GET public String get(@Context UriInfo ui) { MultivaluedMap<String, String> queryParams = ui.getQueryParameters(); MultivaluedMap<String, String> pathParams = ui.getPathParameters(); }

For header and cookie parameters the follow ing:

@GET public String get(@Context HttpHeaders hh) { MultivaluedMap<String, String> headerParams = hh.getRequestHeaders(); Map<String, Cookie> pathParams = hh.getCookies(); }

In general @Context can be used to obtain contextual Java types related to the request or response. For form parameters it is possible to do the follow ing:

@POST @Consumes("application/x-www-form-urlencoded") public void post(MultivaluedMap<String, String> formParams) { // Store the message }

4.1.5. Configure container role based access control via method-permissions in ejb-jar.xml or via access control annotations on EJB.
blah-blah

4.1.6. Configure caller authentication (for access control protected methods) and message protection by Servlet Container via web.xml.
blah-blah

4.1.7. Compile and package.


A JAX-RS application is packaged as a Servlet in a .war file. The Application subclass, resource classes, and providers are packaged in WEB-INF/classes, required libraries are packaged in WEB-INF/lib. Included libraries may also contain resource classes and providers as desired.

4.1.8. Deploy the web service in a Java EE servlet container.


The resources and providers that make up a JAX-RS application are configured via an application-supplied subclass of Application. An implementation may provide alternate mechanisms for locating resource classes and providers (e.g. runtime class scanning) but use of javax.ws.rs.core.Application is the only portable means of configuration:

public abstract class Application { public abstract Set<Class<?>> getClasses(); public Set<Object>getSingletons(); }

The getClasses() method returns a list of classes you w ant to deploy into the JAX-RS environment. They can be @Path annotated classes, in w hich case, you are specifying that you w ant to use the default per-request component model. The getSingletons() method returns actual instances that you create yourself w ithin the implementation
converted by Web2PDFConvert.com

of your Application class. You use this method w hen you w ant to have control over instance creation of your resource classes and providers. JAX-RS provides the deployment agnostic abstract class Application for declaring root resource and provider classes, and root resource and provider singleton instances. A w eb service may extend this class to declare root resource and provider classes. For example:

public class MyApplicaton extends Application { public Set<Class<?>> getClasses() { Set<Class<?>> s = new HashSet<Class<?>>(); s.add(by.boot.java.HelloWorldResource.class); return s; } }

Alternatively it is possible to reuse one of Jersey's implementations that scans for root resource and provider classes given a classpath or a set of package names. Such classes are automatically added to the set of classes that are returned by getClasses. For example, the follow ing scans for root resource and provider classes in packages "by.boot.java", "by.boot.rest" and in any sub-packages of those tw o:

public class MyApplication extends PackagesResourceConfig { public MyApplication() { super("by.boot.java;by.boot.rest"); } }


For servlet deployments JAX-RS specifies that a class that implements Application may be declared instead of a servlet class in <servlet-class> element of a web.xml. This is supported for a w eb container implementing Servlet 3.0 as follow s:

<web-app> <servlet> <servlet-name>Jersey Web Application</servlet-name> <servlet-class>MyApplication</servlet-class> </servlet> <servlet-mapping> <servlet-name>Jersey Web Application</servlet-name> <url-pattern>/resources/*</url-pattern> </servlet-mapping> .... </web-app>

If using Servlet 2.x then instead it is necessary to declare the Jersey specific servlet (or any other JAX-RS implementation-supplied Servlet class) and the application-supplied subclass of Application is identied using an init-param w ith a param-name of javax.ws.rs.Application as follow s:

<web-app> <servlet> <servlet-name>Jersey Web Application</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>MyApplication</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Jersey Web Application</servlet-name> <url-pattern>/resources/*</url-pattern> </servlet-mapping> .... </web-app>

Alternatively a simpler approach is to let Jersey choose the PackagesResourceConfig implementation automatically by declaring the packages as follow s:

<web-app> <servlet> <servlet-name>Jersey Web Application</servlet-name> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name>

converted by Web2PDFConvert.com

<param-value>by.boot.java;by.boot.rest</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Jersey Web Application</servlet-name> <url-pattern>/resources/*</url-pattern> </servlet-mapping> .... </web-app>

Prev 3.2. Create a web service starting from a Java source using JAX-WS

Up Home

Next Chapter 5. Configure Java EE security for a SOAP web service

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 5. Configure Java EE security for a SOAP web service Part I. Exam Objectives

Next

Chapter 5. Configure Java EE security for a SOAP web service 5.1. Configure security requirements of service using Java EE-container based security (overlaps with steps in other tasks repeated here for convenience)
5.1.1. Configure security requirements through deployment descriptors (web.xml, webservices.xml) for a Servlet-based web service endpoint: container authorization, caller authentication, and message protection. JAX-WS runtime may also be configured to perform message layer authentication and protection.
blah-blah

5.1.2. Configure security requirements through deployment descriptors (ejb-jar.xml, webservices.xml) for EJB-based web service endpoint:
5.1.2.1. Configure transactional support. blah 5.1.2.2. Configure container role based access control via method-permissions in ejb-jar.xml or via access control annotations on EJB. blah 5.1.2.3. Configure caller authentication and message protection; either by Servlet container via web.xml, and/or by JAX-WS message processing runtime. blah

5.1.3. Configure security requirements through deployment descriptor (web.xml) for JAX-RS based web service endpoint.
blah-blah
Prev Chapter 4. Create a RESTful web service implemented by an EJB component Up Home Next Chapter 6. Create a web service client for a SOAP based web service

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 6. Create a web service client for a SOAP based web service Part I. Exam Objectives

Next

Chapter 6. Create a web service client for a SOAP based web service 6.1. Create a standalone client.
6.1.1. Use wsimport to generate artifacts.
JAX-W S defines tw o service usage models: Proxy clients. Dispatch clients. In proxy-based client model model, your applications w ork on local proxy objects that implement the SEI that is being exposed by the w eb service endpoint. The dispatch-client model offered by JAX-W S is a low er-level model that requires you to supply the necessary XML request yourself. This model can be used in the situations w here you w ant to dynamically build up the SOAP request itself or w here you must use a non-SOAP-based w eb service endpoint. Collectively, both client types are also know n as BindingProviders because both clients realize the JAX-W S javax.xml.ws.BindingProvider interface. The BindingProvider interface allow s for a common configuration model. Proxy clients The wsimport tool w ill read the W SDL of a deployed w eb service and generate the Java objects necessary to invoke it, including a class that extends javax.xml.ws.Service, w hich provides the client view of a w eb service. This can be a confusing concept because w e tend to think of the service as being located on the server. But a service instance acts as a factory to create proxies that allow you to invoke a w eb service as if it w as local. These proxies are sometimes referred to as SEI (Service Endpoint Interface) objects. The tool generates portable artifacts that use only standard Java means. It w ill automatically call on JAXB to create value types that map Java to XML tand the result can be used to perform w eb services operations. Let's use a simple calculator w eb service as an example. The W SDL of your service is located at http://localhost:4933/CalculatorApp/CalculatorWSService?wsdl. It defines a single port type, as in the follow ing code:

<portType name="CalculatorWS"> <operation name="add"> <input message="tns:add"></input> <output message="tns:addResponse"></output> </operation> </portType> //The service name element is: <service name="CalculatorWSService">

Now run the wsimport tool to create a proxy so you can invoke the service. Here is the command and the output:

>wsimport -d /home/mz -target 2.1 -verbose http://localhost:4933/CalculatorApp/CalculatorWSService?wsdl parsing WSDL... generating code... org\me\calculator\Add.java org\me\calculator\AddResponse.java org\me\calculator\CalculatorWS.java org\me\calculator\CalculatorWSService.java org\me\calculator\ObjectFactory.java org\me\calculator\package-info.java compiling code... javac -d /home/mz -classpath ... >

The wsimport tool has a variety of options, many of w hich have to do w ith customization. But in the basic invocation, you pass the tool the options you w ant and the final argument is the location of the W SDL. The first option, -d, indicates the directory w here you w ant the imported source code to be w ritten. The -target option is used to specify the version of JAX-W S you w ant to be compatible w ith ( 2.0 is the default), and the -verbose option tells the tool to indicate the w ork it is doing as it does it. If you w ant to have wsimport retain the Java source files it generates in addition to the *.class files, use the -keep option.

The generated Service class


In this example, the Service class is called CalculatorWSService.java, w hich corresponds to the value of the name attribute of the W SDL <service> element. The generated Service class allow s you to: Get available ports (service endpoint interfaces). Get the location of the W SDL document associated w ith the service. Get the Executor instance associated w ith the service, w hich provides threading capability to service invocations. Create a Dispatch. Create a Service instance.

converted by Web2PDFConvert.com

Call the getPort method on the Service instance to invoke w eb service operations. This class extends javax.xml.ws.Service, and is annotated w ith a @WebServiceClient annotation that specifies the location of the W SDL representing the service to be invoked. It contains factory methods that return the Java object that represents the W SDL port you can invoke operations on. The generated Service class looks like this:

@WebServiceClient(name = "CalculatorWSService", targetNamespace = "http://calculator.me.org/", wsdlLocation = "http://localhost:4933/CalculatorApp/CalculatorWSService?wsdl") public class CalculatorWSService extends Service { //... @WebEndpoint(name = "CalculatorWSPort") public CalculatorWS getCalculatorWSPort() { return super.getPort(new QName("http://calculator.me.org/", "CalculatorWSPort"), CalculatorWS.class); } //... }
Here the getCalculatorWSPort method returns an object that implements the CalculatorWS interface, w hich is discussed next. The no-arg getPort method can be used in general; the second getPort method accepts a variable-length array of javax.xml.ws.WebServiceFeature objects that can be used by clients to configure certain aspects of the invocation, such as w hether to enable MTOM or W S-Addressing.

The generated Port class


Because the W SDL port as show n in the earlier listing has a value of CalculatorWS for the name attribute, that is the name of the generated Java interface representing the port. This interface is annotated w ith @WebService, to indicate that it is a service endpoint interface that w ill be used as a proxy. There is not an implementation for this class generated by JAX-W S. The runtime w ill do the w ork behind the scenes by delegating the invocation to an implementation of javax.xml.ws.spi.ServiceDelegate, w hich the Service class decorates. In the calculator example, the port has one method, to match the single add operation defined in the W SDL:

@WebMethod @WebResult(targetNamespace = "") @RequestWrapper(localName = "add", targetNamespace = "http://calculator.me.org/", className = "org.me.calculator.Add") @ResponseWrapper(localName = "addResponse", targetNamespace = "http://calculator.me.org/", className = "org.me.calculator.AddResponse") public int add( @WebParam(name = "i", targetNamespace = "") int i, @WebParam(name = "j", targetNamespace = "") int j );
As you can see, the add method has a variety of annotations. First, your W SDL specifies the follow ing in the messages section:

<message name="add"> <part name="parameters" element="tns:add"></part> </message>

So the SEI needs to account for this message, and creates an annotation indicating that the runtime w ill create a message w ith a QName that contains a local part of add, in the specified namespace. That message is derived from the Java class that is also generated, org.me.calculator.Add, w hich looks like this:

@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "add", propOrder = { "i", "j" }) public class Add { protected int i; protected int j; // Getters and setters omitted }
That class acts as the w rapper for each of the integers that w ill be sent in the request. The @XmlXXXXX annotations on this class come from JAXB. They indicate how JAXB should marshal and unmarshal instances of this class to and from XML. The @XmlType annotation is used to specify that this Add class matches a top-level complex type (or an enum) w ithin an XML schema, and the "name" property is specified as "add" in it, to match the item's name w ithin the schema. If you look at the schema that your W SDL refers to, you see the follow ing complex type, w hich matches your Add class:

<xs:complexType name="add"> <xs:sequence>


converted by Web2PDFConvert.com

<xs:element name="i" type="xs:int"></xs:element> <xs:element name="j" type="xs:int"></xs:element> </xs:sequence> </xs:complexType>

Integers are defined as basic types provided w ith XML Schema; they are not custom types that you have w ritten that require something special. The complex type that w raps these tw o integers is created in order to match your W SDL, w hich uses the document/literal style. Here is the portion of the W SDL that tells you this:

<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding> <operation name="add"> <soap:operation soapAction=""></soap:operation> <input> <soap:body use="literal"></soap:body> </input> ... </operation>

Had you been using RPC and not document, the values w ould have been passed separately to the operation invocation just like method parameters. The @RequestWrapper and @ResponseWrapper annotations capture information that JAXB needs to perform the marshaling and unmarshaling operations. If your service is defined as using document/literal mode, this annotation also serves to resolve overloading conflicts.

6.1.2. Create a client application using these artifacts.


Here are the steps in their simplest form. First, w rite the invoker called CalculatorInvoker.java. Navigate to the top-level directory that you passed to the wsimport tool earlier. This w as "/home/mz". You w ill w rite your client there.

import org.me.calculator.*; public class CalculatorInvoker { public static void main(String... arg) { CalculatorWSService service = new CalculatorWSService(); CalculatorWS port = service.getCalculatorWSPort(); int result = port.add(2, 3); System.out.println("Result: " + result); } }
The class in ecxample above simply creates a service instance, uses it to get the port, and uses the port to call the business method, add. Let's compile it, making sure the generated classes in the current directory are on your classpath:

>javac -cp . CalculatorInvoker.java

Then you can run it:

>java -cp . CalculatorInvoker Result: 5


There are a few considerations to keep in mind w ith using generated clients: The client cannot create or destroy w eb service implementations and has no view into its life cycle, w hich is handled entirely on the server. A port object has no identity. It cannot meaningfully be compared to other port objects. You cannot ask for a specific instance of a port. Treat service invocations as stateless. There is no mechanism w ithin Service to handle state across requests. All data binding is performed by JAXB. 6.1.2.1. Invoke web service synchronously or asynchronously. Synchronous clients By using the synchronous model, you can develop SOAP-based w eb service client code w ithout w orrying about the underlying protocol details. Example below show s generated Service subclass:

package by.boot.java; import java.net.MalformedURLException; import java.net.URL;


converted by Web2PDFConvert.com

import import import import import

javax.xml.namespace.QName; javax.xml.ws.Service; javax.xml.ws.WebEndpoint; javax.xml.ws.WebServiceClient; javax.xml.ws.WebServiceFeature;

@WebServiceClient( name = "HelloMessengerService", targetNamespace = "http://java.boot.by/", wsdlLocation = "http://localhost:9999/Hello?wsdl") public class HelloMessengerService extends Service { private final static URL HELLOMESSENGERSERVICE_WSDL_LOCATION; static { URL url = null; try { url = new URL("http://localhost:9999/Hello?wsdl"); } catch (MalformedURLException e) { e.printStackTrace(); } HELLOMESSENGERSERVICE_WSDL_LOCATION = url; } public HelloMessengerService(URL wsdlLocation, QName serviceName) { super(wsdlLocation, serviceName); } public HelloMessengerService() { super(HELLOMESSENGERSERVICE_WSDL_LOCATION, new QName("http://java.boot.by/", "HelloMessengerService")); } @WebEndpoint(name = "HelloMessengerPort") public HelloMessenger getHelloMessengerPort() { return (HelloMessenger) super.getPort( new QName("http://java.boot.by/", "HelloMessengerPort"), HelloMessenger.class); } @WebEndpoint(name = "HelloMessengerPort") public HelloMessenger getHelloMessengerPort(WebServiceFeature... features) { return (HelloMessenger) super.getPort( new QName("http://java.boot.by/", "HelloMessengerPort"), HelloMessenger.class, features); } }

You can tell that class above is a JAX-W S-generated client because of its class-level @WebServiceClient annotation. The class has tw o constructors: The first constructor is the default constructor. It configures the service so that any dynamic proxies created from it are produced by using the W SDL document that w as used to generate the client code. In the HelloMessenger example, the tool w as not instructed to create a local copy of the W SDL document. This is w hy there is an absolute reference to the actual URL at w hich the Endpoint publisher makes the W SDL document available. Because this is not recommended, make sure that you generate the w eb service client code so that it is copied to the client. One of the implications of not having a local W SDL document is that the constructor throw s an exception in cases w here the JAX-W S run time cannot connect to the server that is exposing the document. The second constructor initializes the service by using a specified W SDL document. In addition to these tw o constructors, the generated client has a couple of getHelloMessenger methods w ith w hich you can get a dynamic proxy that binds to the specified w eb service endpoint. The client uses the default constructor to connect to instantiate the w eb service:

HelloMessengerService service = new HelloMessengerService();


This approach can present a problem w hen you w ant the client application to sw itch from the test environment's w eb service endpoint to the production environment's w eb service endpoint. There are a couple of w ays to override this endpoint location from your client code: Use the overloaded constructor of the generated javax.xml.ws.Service subclass that takes another W SDL document location. This supplied W SDL document can, in turn, specify the service endpoint location of interest. Use the default constructor, but specify the endpoint location on the dynamic proxy returned by the service. After the HelloClient application has obtained a HelloMessengerService instance, it uses that instance to obtain a dynamic stub, w hich binds to the actual w eb service endpoint. Example below show s the generated w eb service client type that is implemented by the stub:

package by.boot.java; import import import import javax.jws.WebMethod; javax.jws.WebParam; javax.jws.WebResult; javax.jws.WebService;
converted by Web2PDFConvert.com

import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper; @WebService(name = "HelloMessenger", targetNamespace = "http://java.boot.by/") @XmlSeeAlso({ ObjectFactory.class }) public interface HelloMessenger { @WebMethod @WebResult(targetNamespace = "") @RequestWrapper(localName = "sayHello", targetNamespace = "http://java.boot.by/", className = "by.boot.java.SayHello") @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://java.boot.by/", className = "by.boot.java.SayHelloResponse") public String sayHello( @WebParam(name = "arg0", targetNamespace = "") String arg0); }
The HelloMessenger type is an ordinary Java interface w ith some JAX-W S-specific annotations. Although the return type of the HelloMessengerService is of this interface type, in reality w hat is returned is a dynamic stub that implements this interface. Example below show s a HelloMessenger client application that explicitly specifies, on the dynamic stub, a new w eb service endpoint location:

import by.boot.java.HelloMessenger; import by.boot.java.HelloMessengerService; import javax.xml.ws.BindingProvider; public class HelloClientCustomEndpoint { public static void main(String... args) throws Exception { HelloMessengerService service = new HelloMessengerService(); HelloMessenger port = service.getHelloMessengerPort(); ((BindingProvider)port).getRequestContext().put( BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://hello.com:69693/Hello" ); String message = port.sayHello("Mikalai"); System.out.println(message); } }
The client-relevant code is highlighted in bold. The application casts the dynamic w eb service port proxy to a javax.xml.ws.BindingProvider. The BindingProvider is implemented by the dynamic client proxies and gives you access to the request and the response contexts. The application specifies the endpoint address on the request context using the BindingProvider.ENDPOINT_ADDRESS_PROPERTY property. Asynchronous clients The asynchronous client programming model in JAX-W S is merely a convenient functionality for developing w eb service clients. It does not refer to real asynchronous message exchanges. You can create asynchronous clients by configuring the tool that you use to generate JAX-W S w eb service client code. JAX-W S offers tw o asynchronous programming models: Polling clients. Callback clients. These approaches merely differentiate, in the Java method, signatures that are generated on the client-side w eb service port interface. W hen you enable asynchronous clients in your tool, JAX-W S generates three methods for every operation that is defined in the w eb service portType: One-w ay asynchronous method. An asynchronous polling method. An asynchronous callback method. Example below show s the HelloMessenger client-side endpoint interface that is generated w hen asynchronous method generation is activated by the JAX-W S tool:

package by.boot.java; import import import import import import import import import import java.util.concurrent.Future; javax.jws.WebMethod; javax.jws.WebParam; javax.jws.WebResult; javax.jws.WebService; javax.xml.bind.annotation.XmlSeeAlso; javax.xml.ws.AsyncHandler; javax.xml.ws.RequestWrapper; javax.xml.ws.Response; javax.xml.ws.ResponseWrapper;

converted by Web2PDFConvert.com

@WebService(name = "HelloMessenger", targetNamespace = "http://java.boot.by/") @XmlSeeAlso({ ObjectFactory.class }) public interface HelloMessenger { @WebMethod(operationName = "sayHello") @RequestWrapper(localName = "sayHello", targetNamespace = "http://java.boot.by/", className = "by.boot.java.SayHello") @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://java.boot.by/", className = "by.boot.java.SayHelloResponse") public Response<SayHelloResponse> sayHelloAsync( @WebParam(name = "arg0", targetNamespace = "") String arg0); @WebMethod(operationName = "sayHello") @RequestWrapper(localName = "sayHello", targetNamespace = "http://java.boot.by/", className = "by.boot.java.SayHello") @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://java.boot.by/", className = "by.boot.java.SayHelloResponse") public Future<?> sayHelloAsync( @WebParam(name = "arg0", targetNamespace = "") String arg0, @WebParam(name = "asyncHandler", targetNamespace = "") AsyncHandler<SayHelloResponse> asyncHandler); @WebMethod @WebResult(targetNamespace = "") @RequestWrapper(localName = "sayHello", targetNamespace = "http://java.boot.by/", className = "by.boot.java.SayHello") @ResponseWrapper(localName = "sayHelloResponse", targetNamespace = "http://java.boot.by/", className = "by.boot.java.SayHelloResponse") public String sayHello( @WebParam(name = "arg0", targetNamespace = "") String arg0); }
The method signatures are highlighted in bold. The first signature is used to create asynchronous polling clients. The second signature is used to create asynchronous callback clients. The third signature is used to create synchronous clients and is the signature that is used by the HelloClient application.

Polling clients
The polling client programming model refers to the usage of the asynchronous method that returns a typed javax.xml.ws.Response. Example below show s an asynchronous HelloMessenger w eb service client application:

import import import import

javax.xml.ws.Response; by.boot.java.HelloMessenger; by.boot.java.HelloMessengerService; by.boot.java.SayHelloResponse;

public class HelloAsyncPollingClient { public static void main(String... args) throws Exception { HelloMessengerService service = new HelloMessengerService(); HelloMessenger port = service.getHelloMessengerPort(); Response<SayHelloResponse> sayHelloAsync = port.sayHelloAsync("Mikalai"); while ( ! sayHelloAsync.isDone() ) { // Do something useful for now } // Web service endpoint has now responded: SayHelloResponse sayHelloResponse = sayHelloAsync.get(); String message = sayHelloResponse.getReturn(); System.out.println(message); } }
The relevant code is highlighted in bold. The client application invokes the sayHelloAsync method, w hich returns a response object. This object provides methods to query for response arrival, cancel a response, and get the actual response. The application, in this case, performs a busy w ait, looping until the Response.isDone() method returns true, w hich indicates that the response has been received. The application then fetches the response by using the get() method. This method returns the response w rapper element that contains the actual method return value, w hich in this case is a simple java.lang.String object. If an endpoint throw s a service exception, the get() method can throw a java.util.concurrent.ExecutionException, w hich can then be queried for the cause.

Callback clients
converted by Web2PDFConvert.com

The callback client programming model refers to the usage of the asynchronous method that accepts an input parameter of a typed javax.xml.ws.AsyncHandler. Example below show s an asynchronous callback HelloMessenger w eb service client application:

import import import import import

by.boot.java.HelloMessenger; by.boot.java.HelloMessengerService; by.boot.java.SayHelloResponse; javax.xml.ws.AsyncHandler; javax.xml.ws.Response;

public class HelloAsyncCallbackClient { public static void main(String... args) throws Exception { HelloMessengerService service = new HelloMessengerService(); HelloMessenger port = service.getHelloMessengerPort(); port.sayHelloAsync("Mikalai", new AsyncHandler<SayHelloResponse>() { public void handleResponse(Response<SayHelloResponse> res) { try { SayHelloResponse response = res.get(); String message = response.getReturn(); System.out.println(message); } catch (Exception e) { e.printStackTrace(); } } }); } }
The application passes in an anonymous inner class of type AsyncHandler. This class has a method called handleResponse that is invoked by the JAX-W S runtime w hen the message is received. The argument to this method is of the same type that is used for the polling method, a typed response object. Example above does not show that you can save the return value of the asynchronous method invocation into a java.util.concurrent.Future:

Future<?> future = port.sayHelloAsync("Mikalai", ...);


As is the case w ith the polling response object, you can query this object to obtain status and possibly cancel the operation.

6.1.3. Package and deploy accordingly.


blah-blah
Prev Chapter 5. Configure Java EE security for a SOAP web service Up Home Next 6.2. Create a client in a managed component in a EE container.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

6.2. Create a client in a managed component in a EE container. Chapter 6. Create a web service client for a SOAP based web service

Next

6.2. Create a client in a managed component in a EE container.


6.2.1. Use wsimport to generate artifacts.
blah-blah

6.2.2. Using @WebserviceRef in the client application.


The @WebServiceRef annotation is used to declare a reference to a w eb service. Use the @WebServiceRef annotation to inject a reference to the service you w ant to invoke. Note that this does not have to be only a servlet or EJB. You might also w ant to invoke a w eb service from other container-managed resources, such as a Filter, a SessionContextListener, a ServletContextListener, or a TagHandler depending on your use case. Using @WebServiceRef, you can get a reference to a w eb service and an injection target for it. Items annotated w ith @WebServiceRef follow the standard rules for resource injection w ithin Java EE 6. It defines follw oing attributes or properties, as are described below :

name
A name that identifies the reference to the component using the resource, as a JNDI name. If annotating a field, the default is the name of the field. If annotating a method, the default is the name of the Java Bean property the method defines. If annotating a class, there is no default.

wsdlLocation
The URL pointing to the W SDL for the referenced w eb service. This is necessary if you define your ow n W SDL in a physical file and include it w ith your W AR or EAR.

type
The resource class type. If annotating a field, the default value is the type of the field. If annotating a method, the default is the same as the Java Bean property. If annotating a class, there is no default, and a value must be specified.

value
The service class type, w hich must extend javax.xml.w s.Service. If the reference type is an SEI, this value must be specified.

mappedName
A name, such as a JNDI name, that maps from the value of the "name" property to a resource know n to the server. Any mappedName value is specific to the application server platform, and is non-portable. It is not required that application servers support them.

lookup
A portable JNDI lookup name that resolves to the target w eb service reference. Here you w ill w rite a servlet that invokes the w eb service by injection using the @WebServiceRef annotation. There are a few steps, w hich are exactly the same for using the reference from an EJB client: 1. Create the interface that the w eb service w ill implement, and to w hich clients, such as your servlet, w ill refer. 2. Implement the w eb service. 3. Add the reference annotation to the servlet; an instance of the generated SEI w ill automatically be injected.

Catalog.java in the example below is the interface that clients w ill refer to. It defines a simple operation that returns a book title for a given identifier:

package by.boot.java; import javax.jws.WebMethod; import javax.jws.WebService; /** * Public interface for CatalogWS implementation */ @WebService public interface Catalog { @WebMethod String getTitle(String id); }
Note that you need to include the @WebService annotation on the interface, or the client w ill complain.

CatalogWS.java, show n in the example below , implements the service interface:

package by.boot.java; import javax.jws.WebMethod; import javax.jws.WebService; /** * This annotation will produce a WSDL URL of: * http://localhost:8080/catalogWS/CatalogService?wsdl * That's because it is in the web context of "catalogWS", * which is the WAR name, appended with the value of the * serviceName property. *
converted by Web2PDFConvert.com

* Use that value in the properties file to generate client * artifacts. */ @WebService(serviceName="CatalogService", name="Catalog") public class CatalogWS implements Catalog { @WebMethod @Override public String getTitle(String id) { if ("12345".equals(id)) return "OCE WSD 6 Guide"; if ("67890".equals(id)) return "OCE WSD 6 Quiz"; return "Item not in catalog"; } }
The code in the example below is the servlet that w ill get the @WebServiceRef annotation and receive the service injection from the container at runtime:

@WebServlet(name="CatalogServlet", urlPatterns={"/CatalogServlet"}) public class CatalogServlet extends HttpServlet { @WebServiceRef(type=Catalog.class) private CatalogService service; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); // Service instance injected Catalog port = service.getCatalogPort(); String title = port.getTitle("12345"); try { out.println("..."); out.println("Title= " + title); out.println("..."); } finally { out.close(); } } }
The servlet itself contains the reference to the generated SEI proxy instance, and the container does the injection as it w ould w ith any other injectable resource. There are tw o w ays to use the @WebServiceRef annotation: To define a reference w hose type is a generated service class. In this case, the type and value element w ill both refer to the generated service class type. Moreover, if the reference type can be inferred by the field/method declaration the annotation is applied to, the type and value elements MAY have the default value ( Object.class, that is). If the type cannot be inferred, then at least the type element MUST be present w ith a non-default value.

// Generated Service Class @WebServiceClient(name="StockQuoteService", targetNamespace="...", wsdlLocation="...") public class StockQuoteService extends javax.xml.ws.Service { @WebEndpoint(name="StockQuoteHTTPPort") StockQuoteProvider getStockQuoteHTTPPort() { ... }; ... }

// Generated SEI @WebService(name="StockQuoteProvider", targetNamespace="...") public interface StockQuoteProvider { Double getStockQuote(String ticker); }

// WebServiceRef using the generated service interface type @WebServiceRef public StockQuoteService stockQuoteService;
To define a reference w hose type is a SEI. In this case, the type element MAY be present w ith its default value if the type of the reference can be inferred from the annotated field/method declaration, but the value element MUST alw ays be present and refer to a generated service class type (a subtype of javax.xml.ws.Service).

// WebServiceRef using the SEI type


converted by Web2PDFConvert.com

// stockQuoteProvider proxy is configured with MTOM feature @MTOM @WebServiceRef(StockQuoteService.class) private StockQuoteProvider stockQuoteProvider;
or

// WebServiceRef using the SEI type @WebServiceRef(value=StockQuoteService.class) private StockQuoteProvider stockQuoteProvider;


The value of the wsdlLocation property w ill override the URL established in the generated service class (the class annotated w ith @WebService).

6.2.3. Package and deploy accordingly.


Packaging a servlet endpoint using a WAR Figure 6.1. Servlet endpoint packaging

1. Service Implementation Bean [required] is contained in the WEB-INF/classes/<package-path>/, w here <package-path> is determined by the class's package name. This location is not mandatory, but customary. Alternatively, the SIB could be contained in a JAR under the WEB-INF/lib or even in an extension JAR installed in the w eb container and referenced by the W AR's MANIFEST Class-Path. As long as the SIB is on the application classpath, the packaging w ill w ork. This class file must be annotated w ith @WebService or @WebServiceProvider. Its methods contain the business logic that implements the w eb service operations. 2. Service Endpoint Interface [optional] is contained in the WEB-INF/classes/<package-path>/ w here <package-path> is determined by the class's package name. This location is customary, but not mandatory. The SEI class file may be located anyw here on the application classpath (see classpath description in item 1). W hen used, the SIB's @WebService.endpointInterface attribute's value must equal the complete name of this SEI. 3. W SDL [optional] is contained in the WEB-INF/wsdl directory. This is not a mandatory location, but is customary. W hen used, the SIB's @WebService.wsdlLocation attribute's value must equal the relative location of this file (the wsdlLocation can also be an absolute URL). Any files (e.g., XML Schema denitions) referenced by the W SDL must be referenced relative to the W SDL's location. For example, if the W SDL is in the WEB-INF/wsdl directory and it references a schema as myschema.xsd, then myschema.xsd should be in WEB-INF/wsdl. If the schema is referenced as ../myschema.xsd, myschema.xsd should be in WEB-INF. 4. web.xml [optional] is contained in the WEB-INF/ directory. 5. webservices.xml [optional] is contained in the WEB-INF/ directory. 6. jax-ws-catalog.xml [optional] is contained in the WEB-INF/ directory. This descriptor is used in connection w ith OASIS XML Catalog 1.1 usage. 7. sun-web.xml [optional] is contained in the WEB-INF/ directory. This is the GlassFish-specific w eb application descriptor. 8. Handler Chain Descriptor [optional] is contained under the WEB-INF/classes/ directory w here it w ill be available as a resource on the application classpath. There is no standard name for this file. This is not a mandatory location it may also be specified as an external URL. Specically, w hen used, the SIB's @HandlerChain.file attribute's value must equal either: An absolute java.net.URL in external form (e.g., http://java.boot.by/handlers.xml). A relative path from the source file or class file (e.g., bar/handlers.xml) specifying the location of this file. 9. Dependent Classes [optional] are bundled in a JAR and contained under the WEB-INF/lib directory w here they are available on the application classpath. These are any classes the SIB or SEI depend on. This is not a mandatory location, but one possible approach w hen the SIB depends on a library of classes that may already be packaged in a JAR. The dependent classes may be located anyw here on the application classpath (see classpath description in item 1). Packaging an EJB endpoint using an EJB-JAR Figure 6.2. Stateless or Singleton session bean endpoint packaging

converted by Web2PDFConvert.com

1. Service Implementation Bean [required] is contained in the <package-path>/ directory w here <package-path> is determined by the class's package name. This location is not mandatory, but customary. Alternatively, the SIB could be contained in another JAR (e.g., bundled w ithin an EAR w ith this same EJB-JAR) and referenced by the EJB-JAR's manifest file Class-Path attribute. You could even have the SIB located in an installed library and referenced by the EJB-JAR's manifest file Extension-List attribute. As long as the SIB is on the application classpath, the packaging w ill w ork. This class file must be annotated w ith @Stateless or @Singleton, and @WebService or @WebServiceProvider. Its methods contain the business logic that implements the w eb service operations. 2. Service Endpoint Interface [optional] is contained in the <package-path>/ w here <package-path> is determined by the class's package name. This location is customary, but not mandatory. The SEI class file may be located anyw here on the application classpath (see classpath description in item 1). W hen used, the SIB's @WebService.endpointInterface attribute's value must equal the complete name of this SEI. 3. W SDL [optional] is contained in the META-INF/wsdl/ directory. 4. ejb-jar.xml [optional] is contained in the META-INF/ directory. 5. webservices.xml [optional] is contained in the META-INF/ directory. 6. jax-ws-catalog.xml [optional] is contained in the META-INF/ directory. This descriptor is used in connection w ith OASIS XML Catalog 1.1 usage. 7. sun-ejb-jar.xml [optional] is contained in the META-INF/ directory. This is the GlassFish-specific EJB deployment descriptor. 8. Handler Chain Descriptor [optional] is contained under the / directory w here it is available as a resource on the application classpath. 9. Dependent Classes [optional] are contained in a separate JAR file at the root of the enclosing EAR w here they w ill be available on the application classpath. These are any classes the SIB or SEI depends on. This is not a mandatory location. The dependent classes may be located anyw here on the application classpath (see classpath description in item 1).
Prev Chapter 6. Create a web service client for a SOAP based web service Up Home Next Chapter 7. Create a web service client for a RESTful web service

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 7. Create a web service client for a RESTful web service Part I. Exam Objectives

Next

Chapter 7. Create a web service client for a RESTful web service 7.1. Use a browser to access a JAX-RS resource
blah-blah
Prev 6.2. Create a client in a managed component in a EE container. Up Home Next 7.2. Use the java.net.* APIs to access a JAX-RS resource.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

7.2. Use the java.net.* APIs to access a JAX-RS resource. Chapter 7. Create a web service client for a RESTful web service

Next

7.2. Use the java.net.* APIs to access a JAX-RS resource.


Reading from a URLConnection The follow ing program explicitly retrieves a URLConnection object and gets an input stream from the connection. The connection is opened implicitly by calling getInputStream. Then this program creates a BufferedReader on the input stream and reads from it:

import java.net.*; import java.io.*; public class URLConnectionReader { public static void main(String[] args) throws Exception { URL url = new URL("http://java.boot.by/"); URLConnection urlCon = url.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(urlCon.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println(inputLine); } in.close(); } }
Writing to a URLConnection Many HTML pages contain forms - text fields and other GUI objects that let you enter data to send to the server. After you type in the required information and initiate the query by clicking a button, your w eb brow ser w rites the data to the URL over the netw ork. At the other end the server receives the data, processes it, and then sends you a response, usually in the form of a new HTML page. Many of these HTML forms use the HTTP POST METHOD to send data to the server. Thus w riting to a URL is often called posting to a URL. The server recognizes the POST request and reads the data sent from the client. For a Java program to interact w ith a server-side process it simply must be able to w rite to a URL, thus providing data to the server. It can do this by follow ing these steps: 1. Create a URL. 2. Retrieve the URLConnection object. 3. Set output capability on the URLConnection. 4. Open a connection to the resource. 5. Get an output stream from the connection. 6. W rite to the output stream. 7. Close the output stream. A program creates a URL object, and sets the connection so that it can w rite to it:

URL url = new URL("http://java.boot.by/servlet"); URLConnection connection = url.openConnection(); connection.setDoOutput(true);


The program then creates an output stream on the connection and opens an OutputStreamWriter on it:

OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());


If the URL does not support output, getOutputStream method throw s an UnknownServiceException. If the URL does support output, then this method returns an output stream that is connected to the input stream of the URL on the server side - the client's output is the server's input. Next, the program w rites the required information to the output stream and closes the stream:

out.write("Hello"); out.close();
This code w rites to the output stream using the write method. So you can see that w riting data to a URL is as easy as w riting data to a stream. The data w ritten to the output stream on the client side is the input for the servlet on the server side. Example of RESTful w eb service client:

public int getAge() { // Use the java.net.* APIs to access the Duke's Age RESTful web service HttpURLConnection connection = null; BufferedReader rd = null; StringBuilder sb = null; String line = null; URL serverAddress = null; try {
converted by Web2PDFConvert.com

serverAddress = new URL("http://localhost:8080/DukesAgeService/resources/dukesAge"); connection = (HttpURLConnection) serverAddress.openConnection(); connection.setRequestMethod("GET"); connection.setDoOutput(true); connection.setReadTimeout(10000); // Make the connection to Duke's Age connection.connect(); // Read in the response rd = new BufferedReader(new InputStreamReader(connection.getInputStream())); sb = new StringBuilder(); while ((line = rd.readLine()) != null) { sb.append(line); } // Convert the response to an int age = Integer.parseInt(sb.toString()); } catch (MalformedURLException e) { logger.warning("A MalformedURLException occurred."); e.printStackTrace(); } catch (ProtocolException e) { logger.warning("A ProtocolException occurred."); e.printStackTrace(); } catch (IOException e) { logger.warning("An IOException occurred"); e.printStackTrace(); } return age; }

Prev Chapter 7. Create a web service client for a RESTful web service

Up Home

Next 7.3. Use java.net.Authenticator to access a secure JAX-RS resource.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

7.3. Use java.net.Authenticator to access a secure JAX-RS resource. Chapter 7. Create a web service client for a RESTful web service

Next

7.3. Use java.net.Authenticator to access a secure JAX-RS resource.


java.net.Authenticator
The class Authenticator represents an object that know s how to obtain authentication for a netw ork connection. Usually, it w ill do this by prompting the user for information. Applications use this class by overriding getPasswordAuthentication() in a sub-class. This method w ill typically use the various getXXX() accessor methods to get information about the entity requesting authentication. It must then acquire a username and passw ord either by interacting w ith the user or through some other noninteractive means. The credentials are then returned as a PasswordAuthentication return value. An instance of this concrete sub-class is then registered w ith the system by calling setDefault(Authenticator). W hen authentication is required, the system w ill invoke one of the requestPasswordAuthentication() methods w hich in turn w ill call the getPasswordAuthentication() method of the registered object.

HttpURLConnection supports proxy authentication through the Authenticator class. To enable authentication, your application subclasses Authenticator and defines the getPasswordAuthentication() method. A minimalist implementation is as follow s:

public class SimpleAuthenticator extends Authenticator { private String username, password; public SimpleAuthenticator(String username,String password) { this.username = username; this.password = password; } protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username,password.toCharArray()); } }
Next, it must register the authenticator through Authenticator.setDefault(). If w e adapt the previous code sample to use Authenticator, it looks like this:

String String String String String

url = "http://java.boot.by/"; proxy = "proxy.mydomain.com"; port = "8080"; username = "mikalai"; password = "pwd";

Authenticator.setDefault(new SimpleAuthenticator(username,password)); URL server = new URL(url); Properties systemProperties = System.getProperties(); systemProperties.setProperty("http.proxyHost",proxy); systemProperties.setProperty("http.proxyPort",port); HttpURLConnection connection = (HttpURLConnection)server.openConnection(); connection.connect(); InputStream in = connection.getInputStream(); readResponse(in);

Prev 7.2. Use the java.net.* APIs to access a JAX-RS resource.

Up Home

Next 7.4. Use Ajax to access a JAX-RS resource.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

7.4. Use Ajax to access a JAX-RS resource. Chapter 7. Create a web service client for a RESTful web service

Next

7.4. Use Ajax to access a JAX-RS resource.


Because RESTful w eb services deployed are exposed using the standard HTTP protocol and methods, they can be easily accessed from brow sers. In addition to using simple GET and POST requests directly from brow sers, developers can leverage the capabilities of the JavaScript technology XMLHttpRequest object that most modern brow sers support. This is the same object used for building AJAX user interfaces (UIs):

<html> <head> <title>AJAX RESTFul example</title> <script type="text/javascript" language="javascript"> var http_request = false; function makeAJAXRequest(method, url, parameters) { http_request = false; if (window.XMLHttpRequest) { // Mozilla, Safari http_request = new XMLHttpRequest(); if (http_request.overrideMimeType) { // set type accordingly to anticipated content type http_request.overrideMimeType('text/xml'); } } else if (window.ActiveXObject) { // IE try { http_request = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { http_request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {} } } if (!http_request) { alert('Cannot create XMLHTTP instance'); return false; } http_request.onreadystatechange = alertContents; if(method=='GET') { http_request.open(method, url+parameters, true); http_request.setRequestHeader("Content-type", "text/xml"); http_request.setRequestHeader("Content-length", parameters.length); http_request.setRequestHeader("Connection", "close"); http_request.send(null); } if(method=='POST') { http_request.open(method, url, true); http_request.setRequestHeader("Content-type", "text/xml"); http_request.setRequestHeader("Content-length", parameters.length); http_request.setRequestHeader("Connection", "close"); http_request.send(parameters); } if(method=='PUT') { http_request.open(method, url, true); http_request.setRequestHeader("Content-type", "text/xml"); http_request.setRequestHeader("Content-length", parameters.length); http_request.setRequestHeader("Connection", "close"); http_request.send(parameters); } if(method=='DELETE'){ http_request.open(method, url+parameters, true); http_request.setRequestHeader("Content-type", "text/xml"); http_request.setRequestHeader("Content-length", parameters.length); http_request.setRequestHeader("Connection", "close"); http_request.send(null); } } // function makeAJAXRequest function alertContents() { if (http_request.readyState == 4) { if (http_request.status == 200 || http_request.status==201) { alert('Response received from server:\n'+http_request.responseText); result = http_request.responseText;

converted by Web2PDFConvert.com

// Turn < and > into &lt; and &gt; (case matters) result = result.replace(/\<([^!])/g, '&lt;$1'); result = result.replace(/([^-])\>/g, '$1&gt;'); document.getElementById('serverresponse').innerHTML = result; } else { alert('There was a problem with the request.' +http_request.responseText +' '+http_request.status); document.getElementById('serverresponse').innerHTML = http_request.responseText; } } } // alertContents function postTheForm() { var postStr = document.myform.xmldata.value ; alert('Sending XML to server:\n' + postStr); makeAJAXRequest('POST', document.myform.endpointURL.value , postStr); } function getTheForm() { var getStr = encodeURI(document.myform.xmldata.value) ; alert('Sending XML to server:\n' + getStr); makeAJAXRequest('GET', document.myform.endpointURL.value , getStr); } function putTheForm() { var putStr = document.myform.xmldata.value ; alert('Sending XML to server:\n' + putStr); makeAJAXRequest('PUT', document.myform.endpointURL.value , putStr); } function deleteTheForm() { var delStr = encodeURI(document.myform.xmldata.value); alert('Sending XML to server:\n' + delStr); makeAJAXRequest('DELETE',document.myform.endpointURL.value , delStr); } </script> </head> <body> <form action="javascript:get(document.getElementById('myform'));" name="myform" id="myform"> <input name="endpointURL" type="text" value="http://java.boot.by/restfulwebservice/" > <textarea name="xmldata"> </textarea> <input type="button" name="postbutton" value="send via POST" onclick="javascript:postTheForm();"> <input type="button" name="getbutton" value="send via GET" onclick="javascript:getTheForm();"> <input type="button" name="putbutton" value="send via PUT" onclick="javascript:putTheForm();"> <input type="button" name="deletebutton" value="send via DELETE" onclick="javascript:deleteTheForm();"> </form> <span name="serverresponse" id="serverresponse"></span> </body> </html>

Prev 7.3. Use java.net.Authenticator to access a secure JAX-RS resource.

Up Home

Next 7.5. Use the Jersey client API to access a JAX-RS resource.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

7.5. Use the Jersey client API to access a JAX-RS resource. Chapter 7. Create a web service client for a RESTful web service

Next

7.5. Use the Jersey client API to access a JAX-RS resource.


The Jersey client API is a high-level Java based API for interoperating w ith RESTful Web services. It makes it very easy to interoperate w ith RESTful Web services and enables a developer to concisely and efficiently implement a reusable client-side solution that leverages existing and w ell established client-side HTTP implementations. The Jersey client API can be utilized to interoperate w ith any RESTful Web service, implemented using one of many framew orks, and is not restricted to services implemented using JAX-RS. How ever, developers familiar w ith JAX-RS should find the Jersey client API complementary to their services, especially if the client API is utilized by those services themselves, or to test those services. The goals of the Jersey client API are threefold: 1. Encapsulate a key constraint of the REST architectural style, namely the Uniform Interface Constraint and associated data elements, as client-side Java artifacts; 2. Make it as easy to interoperate w ith RESTful Web services as JAX-RS makes it easy to build RESTful Web services; and 3. Leverage artifacts of the JAX-RS API for the client side. Note that JAX-RS is currently a server-side only API. The Jersey Client API supports a pluggable architecture to enable the use of different underlying HTTP client implementations. Tw o such implementations are supported and leveraged: the Http(s)URLConnection classes supplied w ith the JDK; and the Apache HTTP client.

Uniform Interface Constraint


The uniform interface constraint bounds the architecture of RESTful w eb services so that a client, such as a brow ser, can utilize the same interface to communicate w ith any service. This is a very pow erful concept in softw are engineering that makes Web-based search engines and service mash-ups possible. It induces properties such as: 1. simplicity, the architecture is easier to understand and maintain; and 2. modifiability or loose coupling, clients and services can evolve over time perhaps in new and unexpected w ays, w hile retaining backw ards compatibility. Further constraints are required: 1. every resource is identified by a URI; 2. a client interacts w ith the resource via HTTP requests and responses using a fixed set of HTTP methods; 3. one or more representations can be retured and are identified by media types; and 4. the contents of w hich can link to further resources. The above process repeated over and again should be familiar to anyone w ho has used a brow ser to fill in HTML forms and follow links. That same process is applicable to nonbrow ser based clients. Many existing Java-based client APIs, such as the Apache HTTP client API or java.net.HttpURLConnection supplied w ith the JDK place too much focus on the Client-Server constraint for the exchanges of request and responses rather than a resource, identified by a URI, and the use of a fixed set of HTTP methods. A resource in the Jersey client API is an instance of the Java class WebResource, and encapsulates a URI. The fixed set of HTTP methods are methods on WebResource or if using the builder pattern (more on this later) are the last methods to be called w hen invoking an HTTP method on a resource. The representations are Java types, instances of w hich, may contain links that new instances of WebResource may be created from.

Ease of use and reusing JAX-RS artifacts


Since a resource is represented as a Java type it makes it easy to configure, pass around and inject in w ays that is not so intuitive or possible w ith other client-side APIs. The Jersey Client API reuses many aspects of the JAX-RS and the Jersey implementation such as: 1. URI building using UriBuilder and UriTemplate to safely build URIs; 2. Support for Java types of representations such as byte[], String, InputStream, File, DataSource and JAXB beans in addition to Jersey specific features such as JSON support and MIME Multipart support. 3. Using the builder pattern to make it easier to construct requests. Some APIs, like the Apache HTTP client or java.net.HttpURLConnection, can be rather hard to use and/or require too much code to do something relatively simple. This is w hy the Jersey Client API provides support for w rapping HttpURLConnection and the Apache HTTP client. Thus it is possible to get the benefits of the established implementations and features w hile getting the ease of use benefit. It is not intuitive to send a POST request w ith form parameters and receive a response as a JAXB object w ith such an API. For example w ith the Jersey API this is very easy:

Form f = new Form(); f.add("x", "foo"); f.add("y", "bar"); Client c = Client.create(); WebResource r = c.resource("http://localhost:8080/form"); JAXBBean bean = r .type(MediaType.APPLICATION_FORM_URLENCODED_TYPE) .accept(MediaType.APPLICATION_JSON_TYPE) .post(JAXBBean.class, f);
In the above code a Form is created w ith tw o parameters, a new WebResource instance is created from a Client then the Form instance is POSTed to the resource, identified w ith the form media type, and the response is requested as an instance of a JAXB bean w ith an acceptable media type identifying the Java Script Object Notation (JSON) format. The Jersey client API manages the serialization of the Form instance to produce the request and de-serialization of the response to consume as an instance of a JAXB bean. If the code above w as w ritten using HttpURLConnection then the developer w ould have to w rite code to serialize the form sent in the POST request and de-serialize the response to the JAXB bean. In addition further code w ould have to be w ritten to make it easy to reuse the same resource "http://localhost:8080/form" that is encapsulated in the WebResource type.

Overview of the API

converted by Web2PDFConvert.com

To utilize the client API it is first necessary to create an instance of a Client, for example:

Client c = Client.create();
The client instance can then be configured by setting properties on the map returned from the getProperties methods or by calling the specific setter methods, for example the follow ing configures the client to perform automatic redirection for appropriate responses:

c.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true);
w hich is equivalent to the follow ing:

c.setFollowRedirects(true);
Alternatively it is possible to create a Client instance using a ClientConfig object for example:

ClientConfig cc = new DefaultClientConfig(); cc.getProperties().put(ClientConfig.PROPERTY_FOLLOW_REDIRECTS, true); Client c = Client.create(cc);


Once a client instance is created and configured it is then possible to obtain a WebResource instance, w hich w ill inherit the configuration declared on the client instance. For example, the follow ing creates a reference to a Web resource w ith the URI "http://localhost:8080/xyz":

WebResource r = c.resource("http://localhost:8080/xyz");
and redirection w ill be configured for responses to requests invoked on the Web resource.

Client instances are expensive resources. It is recommended a configured instance is reused for the creation of Web resources. The creation of Web resources, the building of requests and receiving of responses are guaranteed to be thread safe. Thus a Client instance and WebResource instances may be shared betw een multiple threads.
In the above cases a WebResource instance w ill utilize HttpUrlConnection or HttpsUrlConnection, if the URI scheme of the WebResource is "http" or "https" respectively. Requests to a Web resource are built using the builder pattern ( RequestBuilder) w here the terminating method corresponds to an HTTP method ( UniformInterface). For example:

String response = r.accept( MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_XML_TYPE). header("X-FOO", "BAR"). get(String.class);


The above sends a GET request w ith an Accept header of application/json, application/xml and a non-standard header X-FOO of BAR. If the request has a request entity (or representation) then an instance of a Java type can be declared in the terminating HTTP method, for PUT, POST and DELETE requests. For example, the follow ing sends a POST request:

String request = "content"; String response = r.accept( MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_XML_TYPE). header("X-FOO", "BAR"). post(String.class, request);
w here the String "content" w ill be serialized as the request entity. The Content-Type of the request entity may be declared using the type builder method as follow s:

String response = r.accept( MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_XML_TYPE). header("X-FOO", "BAR"). type(MediaType.TEXT_PLAIN_TYPE). post(String.class, request);
or alternatively the request entity and type may be declared using the entity method as follow s:

String response = r.accept( MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_XML_TYPE). header("X-FOO", "BAR"). entity(request, MediaType.TEXT_PLAIN_TYPE). post(String.class);
If the response has a entity (or representation) then the Java type of the instance required is declared in the terminating HTTP method. In the above examples a response entity is expected and an instance of String is requested. The response entity w ill be de-serialized to a String instance.

converted by Web2PDFConvert.com

If response meta-data is required then the Java type ClientResponse can be declared from w hich the response status, headers and entity may be obtained. For example, the follow ing gets both the entity tag and response entity from the response:

ClientResponse response = r.get(ClientResponse.class); EntityTag e = response.getEntityTag(); String entity = response.getEntity(String.class);


If the ClientResponse type is not utilized and the response status is greater than or equal to 300 then the runtime exception UniformInterfaceException is throw n. This exception may be caught and the ClientResponse obtained as follow s:

try { String entity = r.get(String.class); } catch (UniformInterfaceException ue) { ClientResponse response = ue.getResponse(); }
A new WebResource can be created from an existing WebResource by building from the latter's URI. Thus it is possible to build the request URI before building the request. For example, the follow ing appends a new path segment and adds some query parameters:

WebResource r = c.resource("http://localhost:8080/xyz"); MultivaluedMap<String, String> params = MultivaluedMapImpl(); params.add("foo", "x"); params.add("bar", "y"); String response = r.path("abc"). queryParams(params). get(String.class);

that results in a GET request to the URI "http://localhost:8080/xyz/abc?foo=x&bar=y". All the Java types for representations supported by the Jersey server side for requests and responses are also supported on the client side. This includes the standard Java types as specified by JAX-RS in section 4.2.4 in addition to JSON, Atom and Multipart MIME as supported by Jersey. To process a response entity (or representation) as a stream of bytes use InputStream as follow s:

InputStream in = r.get(InputStream.class); // Read from the stream ... in.close();


Note that it is important to close the stream after processing so that resources are freed up. To POST a file use File as follow s:

File f = ... String response = r.post(String.class, f);


Adding support for new representations
The support for new application-defined representations as Java types requires the implementation of the same provider-based interfaces as for the server side JAX-RS API, namely MessageBodyReader and MessageBodyWriter, respectively, for request and response entities (or inbound and outbound representations). Classes or implementations of the provider-based interfaces need to be registered w ith a ClientConfig and passed to the Client for creation. The follow ing registers a provider class MyReader w hich w ill be instantiated by Jersey:

ClientConfig cc = new DefaultClientConfig(); cc.getClasses().add(MyReader.class); Client c = Client.create(cc);


The follow ing registers an instance or singleton of MyReader:

ClientConfig cc = new DefaultClientConfig(); MyReader reader = ... cc.getSingletons().add(reader); Client c = Client.create(cc);

Prev 7.4. Use Ajax to access a JAX-RS resource.

Up Home

Next 7.6. Use the JAX-WS HTTP binding to access a JAX-RS resource.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

7.6. Use the JAX-WS HTTP binding to access a JAX-RS resource. Chapter 7. Create a web service client for a RESTful web service

Next

7.6. Use the JAX-WS HTTP binding to access a JAX-RS resource.


JAX-W S enables a client to consume RESTful w eb services programmatically. The main API is the javax.xml.ws.Dispatch interface described in code sample below :

// T is the message type. public interface Dispatch<T> { // synchronous request-response T invoke(T msg) throws WebServiceException; // async request-response Response<T> invokeAsync(T msg) throws WebServiceException; Future<?> invokeAsync(T msg, AsyncHandler<T> h) throws WebServiceException; // one-way void invokeOneWay(T msg) throws WebServiceException; }

Unlike the Provider on the server side, developers do not actually implement this API. Instead, they obtain an instance from the Service object as show n here:

// Endpoint Address String endpointAddress = "http://java.boot.by/rest"; // Qname for Service QName serviceName = new Qname("http://java.boot.by/rest", "PO"); Service service = Service.create(serviceName); service.addPort(portName, HTTPBinding.HTTP_BINDING, endpointAddress); Dispatch<Source> dispatch = service.createDispatch(new QName("", ""), Source.class, Service.Mode.PAYLOAD); Map<String, Object> requestContext = dispatch.getRequestContext(); requestContext.put(MessageContext.HTTP_REQUEST_METHOD, "GET"); Source result = d.invoke(null); if (result != null) { ... }

Once you specify the address of the service, you pass it into the Service.addPort method along w ith the HTTPBinding constant instead of the SOAP binding you use w ith SOAP messages. Then use the request context you get from the Dispatch to indicate that you are using the HTTP GET method. The runtime w ill use the properties in this map to help it create the proper request and send it off. The Dispatch returns a Source, w hich can be transformed into a number of Source-related objects suitable for different purposes. The typed Dispatch<T> interface and the invoke method can accept and return four major datatypes:

Dispatch<javax.xml.transform.Source> Source objects are low level objects that hold XML documents. Each Source implementation provides methods that access the stored XML documents and manipulate its contents. The follow ing objects implement the Source interface: DOMSource SAXSource StreamSource Dispatch<javax.xml.soap.SOAPMessage> Dispatch objects can use javax.xml.soap.SOAPMessage objects w hen the follow ing conditions are true:
the Dispatch object is using the SOAP binding. the Dispatch object is using message mode.

Dispatch<javax.activation.DataSource> Dispatch objects can use objects that implement the javax.activation.DataSource interface w hen the follow ing conditions are true:
the Dispatch object is using the HTTP binding. the Dispatch object is using message mode.

DataSource objects provide a mechanism for w orking w ith MIME typed data from a variety of sources including URLs, files, and byte arrays. Dispatch<Object>
W hile Dispatch objects are intended to be low level API that allow s you to w ork w ith raw messages, they also allow you to w ork w ith JAXB objects. To w ork w ith JAXB objects a Dispatch object must be passed a JAXBContext that know s how to marshal and unmarshal the JAXB objects in use. The JAXBContext is passed

converted by Web2PDFConvert.com

w hen the Dispatch object is created. You can pass any JAXB object understood by the JAXBContext object as the parameter to the invoke(...) method. You can also cast the returned message into any JAXB object understood by the JAXBContext object. Code fragment below demonstrates how to make a POST request to http://java.boot.by/rest/acceptPO w ith the XML as the body of the POST request read from a poXML String:

private void acceptPO() { Service service = Service.create(serviceName); service.addPort(portName, HTTPBinding.HTTP_BINDING, endpointAddress + "/acceptPO"); Dispatch<Source> dispatcher = service.createDispatch(qname, Source.class, Service.Mode.PAYLOAD); Map<String, Object> requestContext = dispatcher.getRequestContext(); requestContext.put(MessageContext.HTTP_REQUEST_METHOD, "POST"); Source result = dispatcher.invoke(new StreamSource(new StringReader(poXML))); printSource(result); }

Code fragment below demonstrates how to make a similar POST request, but it sends and returns JAXB-generated objects rather than handling strings directly:

private void acceptPOJAXB() throws JAXBException { JAXBContext jc = ... Service service = Service.create(serviceName); service.addPort(portName, HTTPBinding.HTTP_BINDING, endpointAddress + "/acceptPO"); Dispatch<Object> dispatcher = service.createDispatch(qname, jc, Service.Mode.PAYLOAD); Map<String, Object> requestContext = dispatcher.getRequestContext(); requestContext.put(MessageContext.HTTP_REQUEST_METHOD, "POST"); JAXBElement<PurchaseOrder> order = new ObjectFactory().createPurchaseOrderDocument(createPO()); JAXBElement<PurchaseOrderStatus> response = (JAXBElement<PurchaseOrderStatus>)dispatcher.invoke(order); PurchaseOrderStatus result= response.getValue(); System.out.println("Order id is : " + result.getOrderid()); System.out.println("Timestamp is : " + result.getTimestamp()); }

Code fragment below demonstrates how to make a similar PUT request using the Dispatch interface:

private void updatePO() { Service service = Service.create(serviceName); service.addPort(portName, HTTPBinding.HTTP_BINDING, endpointAddress + "/updatePO"); Dispatch<Source> dispatcher = service.createDispatch(qname, Source.class, Service.Mode.PAYLOAD); Map<String, Object> requestContext = dispatcher.getRequestContext(); requestContext.put(MessageContext.HTTP_REQUEST_METHOD, "PUT"); Source result = dispatcher.invoke(new StreamSource(new StringReader(poXML))); printSource(result); }

Prev 7.5. Use the Jersey client API to access a JAX-RS resource.

Up Home

Next Chapter 8. Create a SOAP based web service using Java SE platform.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 8. Create a SOAP based web service using Java SE platform. Part I. Exam Objectives

Next

Chapter 8. Create a SOAP based web service using Java SE platform. 8.1. Create a web service starting from a WSDL file using JAX-WS.
8.1.1. Use wsimport tool to generate artifacts and use customization files for wsimports if needed.
The wsimport command-line tool processes an existing Web Services Description Language (W SDL) file and generates the required portable artifacts for developing Java API for XML-Based Web Services (JAX-W S) w eb service applications. The wsimport command-line tool supports the top-dow n approach to developing JAX-W S w eb services. W hen you start w ith an existing W SDL file, use the wsimport command-line tool to generate the required JAX-W S portable artifacts. The wsimport tool reads an existing W SDL file and generates the follow ing portable artifacts: Service Endpoint Interface (SEI) - The SEI is the annotated Java representation of the W SDL file for the w eb service. This interface is used for implementing JavaBeans endpoints or creating dynamic proxy client instances.

javax.xml.ws.Service extension class - This is a generated class that extends the javax.xml.ws.Service class. This class is used to configure and create both
dynamic proxy and dispatch instances. Java Architecture for XML Binding (JAXB) beans that are required to model the w eb service data. Exception class mapped from wsdl:fault (if any). Async Reponse Bean derived from response wsdl:message (if any). Syntax:

wsimport [options] <wsdl>

-d directory
Specify w here to place generated output files.

-b path
Specifies the external JAX-W S or JAXB binding files. You can specify multiple JAX-W S and JAXB binding files by using the -b option; how ever, each file must be specified w ith its ow n -b option.

-keep
Keep generated files.

-p
Specifying a target package via this command-line option, overrides any w sdl and schema binding customization for package name and the default package name algorithm defined in the specification.

-s directory
Specify w here to place generated source files.

-wsdllocation location
The w sdl URI passed thru this option w ill be used to set the value of @WebService.wsdlLocation and @WebServiceClient.wsdlLocation annotation elements on the generated SEI and Service interface. Multiple JAX-W S and JAXB binding files can be specified using -b option and they can be used to customize various things like package names, bean names, etc. Examples: This command generates JAX-W S portable artifacts for http://example.org/stock?wsdl in to the generated directory:

wsimport -d generated http://example.org/stock?wsdl


This command generates JAX-W S artifacts for stock.wsdl and uses the customization files stock.xml (JAX-W S customization file) and stock.xjb (JAXB customization file) in the process:

wsimport stock.wsdl -b stock.xml -b stock.xjb

8.1.2. Build the web service implementation using the above artifacts.
For SOAP-based services, the W SDL represents the contract. This model has a single overarching paradigm: the W SDL defines the primary features of the contract for the service, and implementation-independent contracts are one of the cornerstone necessities of SOA. The contract is not an afterthought, but rather a central concern. W ith this model, you w rite the W SDL yourself by hand, generate a Java code shell for the service implementation, and then fill in the business logic for the service implementation. This method is also sometimes referred to as "Contract First." You start by taking a preexisting abstract W SDL and pointing it to a tool such as wsimport that produces a service endpoint interface in addition to Java classes that represent the schema definitions and message parts specified in the W SDL. Once the endpoint interface has been generated, w rite a Java class that implements that interface. The basic steps are as follow s: 1. W rite a W SDL representing the service you w ant to deploy. 2. Generate client-side code using wsimport. Among other things, this w ill generate a service interface for each portType.

converted by Web2PDFConvert.com

3. Implement each interface by w riting your w eb service implementation class. That means doing something like this:

@WebService( endpointInterface="by.boot.java.MyGeneratedInterface", wsdlLocation="/META-INF/wsdl/MyWsdl.wsdl" ) public class MyService implements MyGeneratedInterface { ... }


4. Deploy the service endpoint implementation to a JAX-W S-compatible container. In this example, the endpoint interface is specified as a fully qualified name of the interface that wsimport generated, w ritten as a string. The W SDL location property allow s you to specify either a relative or an absolute URI. If relative, it must be in META-INF/wsdl. On a practical level, your organization might benefit from having a published W SDL released early in the project, so that client- and server-side development teams can w ork independently. Another key benefit to starting from W SDL is that XML schema affords a far richer set of data types than many programming languages. Starting from W SDL, you can offer a set of type options, maximizing interoperability.

8.1.3. Use Endpoint API to configure and deploy it in Java SE 6 platform.


The Endpoint class can be used to create and publish w eb service endpoints. An endpoint consists of an object that acts as the w eb service implementation (called here implementor) plus some configuration information, e.g. a Binding. Implementor and binding are set w hen the endpoint is created and cannot be modified later. Their values can be retrieved using the getImplementor and getBinding methods respectively. Other configuration information may be set at any time after the creation of an Endpoint but before its publication. Endpoints can be created using the follow ing static methods on Endpoint:

create(Object implementor)
Creates and returns an Endpoint for the specified implementor. If the implementor specifies a binding using the javax.xml.ws.BindingType annotation it MUST be used else a default binding of SOAP 1.1 / HTTP binding MUST be used.

Endpoint endpoint = Endpoint.create(new ExamplePort()); endpoint.publish("http://localhost:8080/exampleApp/ExampleService");

create(Object implementor, WebServiceFeature... features)


Same as the above create() method. The created Endpoint is configured w ith the w eb service features. These features override the corresponding features that are specied in W SDL, if present.

create(String bindingID, Object implementor)


Creates and returns an Endpoint for the specified binding and implementor. If the bindingID is null and no binding information is specified via the javax.xml.ws.BindingType annotation then a default SOAP 1.1 / HTTP binding MUST be used.

create(String bindingID, Object implementor, WebServiceFeature... features)


Same as the above create() method. The created Endpoint is configured w ith the w eb service features. These features override the corresponding features that are specied in W SDL, if present.

publish(String address, Object implementor)


Creates and publishes an Endpoint for the given implementor. The binding is chosen by default based on the URL scheme of the provided address (w hich must be a URL). If a suitable binding if found, the endpoint is created then published as if the Endpoint.publish(String address) method had been called. The created Endpoint is then returned as the value of the method. The follow ing code provides an example of its use:

// assume Test is an endpoint implementation class annotated with @WebService Test test = new Test(); Endpoint e = Endpoint.publish("http://localhost:8080/test", test);

publish(String address, Object implementor, WebServiceFeature... features)


Same as the above publish() method. The created Endpoint is congured w ith the w eb service features. These features override the corresponding features that are specied in W SDL, if present. An Endpoint is in one of three states: not published (the default), published or stopped. Published endpoints are active and capable of receiving incoming requests and dispatching them to their implementor. Non published endpoints are inactive. Stopped endpoint w ere in the published until some time ago, then got stopped. Stopped endpoints cannot be published again. Publication of an Endpoint can be achieved by invoking one of the follow ing methods:

publish(String address)
Publishes the endpoint at the specified address (a URL). The address MUST use a URL scheme compatible w ith the endpoint's binding.

publish(Object serverContext)
Publishes the endpoint using the specified server context. The server context MUST contain address information for the resulting endpoint and it MUST be compatible w ith the endpoint's binding. The follow ing example show s the use of the publish(Object) method using a hypothetical HTTP server API that includes the HttpServer and HttpContext classes:

// assume Test is an endpoint implementation class annotated with @WebService Test test = new Test();

converted by Web2PDFConvert.com

HttpServer server = HttpServer.create(new InetSocketAddress(8080), 10); server.setExecutor(Executor.newFixedThreadPool(10)); server.start(); HttpContext context = server.createContext("/test"); Endpoint endpoint = Endpoint.create(SOAPBinding.SOAP11HTTP_BINDING, test); endpoint.publish(context);

Prev 7.6. Use the JAX-WS HTTP binding to access a JAX-RS resource.

Up Home

Next 8.2. Create a web service starting from a Java source using JAX-WS.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

8.2. Create a web service starting from a Java source using JAX-WS. Chapter 8. Create a SOAP based web service using Java SE platform.

Next

8.2. Create a web service starting from a Java source using JAX-WS.
8.2.1. Use wsgen tool to generate artifacts in Java EE5 (optional in Java EE6 - as artifacts are generated at run time)
The wsgen command-line tool generates the necessary portable artifacts required for Java API for XML Web Services (JAX-W S) applications w hen starting from Java code. This tool w ill generate a W SDL file only w hen requested. W hen using a bottoms-up approach to develop JAX-W S w eb services and you are starting from a service endpoint implementation, use the wsgen tool to generate the required JAX-W S portable artifacts. The wsgen tool accepts a properly annotated service endpoint implementation using the @WebService annotation as input and generates the follow ing portable artifacts: any additional Java Architecture for XML Binding (JAXB) classes that are required to marshal and unmarshal the message contents. a W SDL file if the optional -wsdl argument is specified. The wsgen tool does not automatically generate the W SDL file. The command line syntax is:

wsgen [options] service_implementation_class


The service_implementation_class name is the only parameter that is required. The follow ing parameters are optional for the wsgen command:

-classpath <path>
Specifies the location of the service implementation class.

-cp <path>
This is the same as -classpath <path>.

-d <directory>
Specifies w here to place the generated output files.

-extension
Specifies w hether to allow custom extensions for functionality not specified by the JAX-W S specification. Use of the extensions can result in applications that are not portable or do not interoperate w ith other implementations.

-keep
Specifies w hether to keep the generated source files.

-r <directory>
This parameter is only used in conjunction w ith the -wsdl parameter. Specifies w here to place the generated W SDL file.

-s <directory>
Specifies the directory to place the generated source files.

-wsdl [:protocol]
By default, wsgen does not generate a W SDL file. This optional parameter causes wsgen to generate a W SDL file and is typically only used to allow a developer to review a W SDL file before the endpoint is deployed. The protocol is optional and specifies the protocol used in the wsdl:binding. Valid values for protocol are soap 1.1 and Xsoap 1.2. The default value is soap 1.1. The Xsoap 1.2 value is not standard and can only be used in conjunction w ith the -extension option.

-servicename <name>
This parameter is only used in conjunction w ith the -wsdl option. Specifies a wsdl:service name to be generated in the W SDL file. For example:

-servicename "{http://mynamespace/}MyService"

-portname
This parameter is only used in conjunction w ith the -wsdl option. Specifies a wsdl:port name to be generated in the W SDL file. For example:

-portname "{http://mynamespace/}MyPort"
Note that you must run wsgen against a Java class that has already been compiled (not against the source program), and if you specify a directory in w hich the tool should place generated files such as the W SDL, that directory must exist before you run the program. Also, you must run the tool against an implementation class, and not an interface.

8.2.2. Use Endpoint API to configure and deploy it in Java SE 6 platform.


blah-blah
Prev Chapter 8. Create a SOAP based web service using Java SE platform. Up Home Next Chapter 9. Create handlers for SOAP web services.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 9. Create handlers for SOAP web services. Part I. Exam Objectives

Next

Chapter 9. Create handlers for SOAP web services.


The handler framew ork allow s interception of a message at various points in its transmission. Handlers are simple Java bean classes that implement a handler contract and can be associated w ith w eb service endpoints and w eb service clients. W ith outgoing messages, handlers are invoked before a message is sent to the w ire. W ith incoming messages, handlers are invoked before the receiving application receives the message. The same handler implementation is used for both incoming and outgoing messages. JAX-W S provides tw o levels of handlers: Logical handlers deal w ith the payload level of the message. Logical handlers can be used for building non-functional behavior, such as logging and caching, that is common across protocols. Protocol handlers deal w ith protocol information, such as SOAP headers. Logical handlers Example below show s a logical handler skeleton. The main method is the handleMessage method. The close method is to clean up any resources that handler invocation might have consumed. The handleFault method is invoked if an error condition occurs, for example, if a response message contains a fault.

import javax.xml.ws.handler.LogicalHandler; import javax.xml.ws.handler.LogicalMessageContext; import javax.xml.ws.handler.MessageContext; public class HelloMessengerLogicalHandler implements LogicalHandler<LogicalMessageContext> { public void close(MessageContext ctx) { } public boolean handleFault(LogicalMessageContext ctx) { return false; } public boolean handleMessage(LogicalMessageContext ctx) { return false; } }

The handleMessage method (and handleFault) return a boolean. Returning true from the handleMessage method tells the JAX-W S run time that processing should move to the next handler in the chain. Returning false tells the JAX-W S run time that processing of the handler chain should end. The parameter to handleMessage is a LogicalMessageContext. It is an extension of java.util.Map and contains <key, value> pairs of context properties. There are properties for items such as W SDL element names and attachment information (if any). Since handlers are invoked for both incoming and outgoing messages, a useful property is the MESSAGE_OUTBOUND_PROPERTY defined on the MessageContext interface, w hich gives you the direction of the message:

Boolean outbound = ctx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);


Another useful property is the message itself:

LogicalMessage message = ctx.getMessage();


You can get the payload as XML data by using the javax.xml.transform.Source:

Source payload = message.getPayload();


Alternatively, you can get the payload as JAXB objects:

Object jaxbPayload = message.getPayload(jaxbContext);


In either case, you get the payload. In the case of SOAP, the payload is the contents of the SOAP:Body, either in XML form ( javax.xml.transform.Source) or in JAXB form ( java.lang.Object). Protocol handlers The primary reason for w riting a SOAP handler is to manipulate SOAP headers. Example below show s an example of a SOAP handler skeleton:

import import import import import

java.util.Set; javax.xml.namespace.QName; javax.xml.ws.handler.MessageContext; javax.xml.ws.handler.soap.SOAPHandler; javax.xml.ws.handler.soap.SOAPMessageContext;

public class HelloMessengerProtocolHandler implements SOAPHandler<SOAPMessageContext> { public Set<QName> getHeaders() { return null; }
converted by Web2PDFConvert.com

public void close(MessageContext ctx) { } public boolean handleFault(SOAPMessageContext ctx) { return false; } public boolean handleMessage(SOAPMessageContext ctx) { return false; } }

The SOAP handler skeleton has the familiar methods of close, handleFault, and handleMessage. The parameter to handleFault and handleMessage, how ever, is now SOAPMessageContext instead of LogicalMessageContext. In addition, the getHeaders method is a new method to implement. The getHeaders method returns the set of the header names that the handler understands. The JAX-W S run time calls this method to determine w hether the handler can process SOAP headers that must be understood (as indicated by the SOAP mustUnderstand attribute). It does not call this method to filter handler invocation. All handlers in a chain are called for all messages. The SOAPMessageContext class adds a few properties to the context map that are SOAP-specific, such as roles. The getMessage method returns a SOAPMessage, w hich is an SAAJ class. By using the SOAPMessage, you can programmatically examine or modify SOAP message headers.

9.1. Configure SOAP and logical handlers on the server side.


9.1.1. Use @HandlerChain annotation.
W ith JAX-W S, you can declaratively specify a w eb service handler chain by using the @javax.jws.HandlerChain annotation. Example below show s how to apply a handler chain to the HelloMessenger w eb service:

import javax.jws.HandlerChain; import javax.jws.WebService; @WebService @HandlerChain(file = "handler-chain.xml") public class HelloMessenger { public String sayHello(String name) { return String.format("Hello %s", name); } }
The HelloMessenger w eb service contains a class-level @HandlerChain annotation, w hich specifies that the handler configuration should be loaded from the handlerchain.xml file that is available in the class path. Example below show s the handler-chain.xml file in its entirety:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <javaee:handler-chain> <javaee:handler> <javaee:handler-class>HelloMessengerProtocolHandler</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </javaee:handler-chains>

The XML file tells the JAX-W S run time to use the HelloMessengerProtocolHandler to handle incoming and outgoing messages.

9.1.2. Use deployment descriptors.


The webservices.xml deployment descriptor file w as introduced by the first version of [JSR 109] to define the set of w eb services that are to be deployed in a container. How ever, w ith JAX-W S, the use of webservices.xml is optional since the annotations can be used to specify most of the information specified in this deployment descriptor. W hen you are deploying JAX-W S w eb services, the only reason you should use webservices.xml is to override or augment the annotation member attributes or w hen you do not w ant to use annotations because you don't w ant to modify the Java source code. One situation, w here you might w ant to override or augment annotations, occurs w hen you w ant to deploy a handler w ith a w eb service endpoint that has not been annotated for a handler. Alternatively, the endpoint may have been annotated for a handler, but you w ish to use a different handler. One w ay to deal w ith this is to edit the source code to update or add the @HandlerChain annotation. But perhaps you do not have access or authority to modify the source code. Or perhaps you think it is a bad idea to have multiple versions of the same source code just so you can support using the endpoint w ith different handlers. In such a situation, you can deploy the endpoint w ith a custom webservices.xml to specify the handler chain. Example below show s the Hello w eb service endpoint w ith an @HandlerChain annotation that specifies the myhandler.xml handler configuration file:

@HandlerChain(file="myhandler.xml") @WebService public class Hello { @Resource WebServiceContext context; public String sayHello(String s) { String appendString = (String) context.getMessageContext().get(HelloHandler.APPEND_STRING); return "Hello: " + s + "[appended by handler: " + appendString + "]"; }
converted by Web2PDFConvert.com

}
The myhandler.xml file is show n in below . Notice that it specifies the handler class HelloHandler.

<handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee"> <handler-chain> <handler> <handler-class>HelloHandler</handler-class> </handler> </handler-chain> </handler-chains>

Now , suppose you w ould prefer to deploy this endpoint w ith the handler class ImprovedHelloHandler. You could do that by bundling the webservices.xml file show n below in the WEB-INF directory of the W AR module (or, if this w ere an EJB endpoint, in the META-INF directory). The webservices.xml overrides the @HandlerChain annotation:

<webservices xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://www.ibm.com/webservices/xsd/javaee_web_services_1_2.xsd"> <webservice-description> <webservice-description-name>HelloService</webservice-description-name> <port-component> <port-component-name>Hello</port-component-name> <wsdl-service xmlns:ns1="http://samples/">ns1:HelloService</wsdl-service> <wsdl-port xmlns:ns1="http://samples/">ns1:HelloPort</wsdl-port> <service-impl-bean> <servlet-link>Hello</servlet-link> </service-impl-bean> <handler-chains> <handler-chain> <handler> <handler-name>myhandler</handler-name> <handler-class>ImprovedHelloHandler</handler-class> </handler> </handler-chain> </handler-chains> </port-component> </webservice-description> </webservices>

In this webservices.xml deployment descriptor, notice the handler-chains element in the bottom half of the listing. Here, the handler-class element specifies ImprovedHelloHandler. W hen using the webservice.xml, it is important to understand how the port-component names match up w ith the annotations. In other w ords, port-component-name relates to @WebService.name; wsdl-service relates to @WebService.serviceName; wsdl-port relates to @WebService.portName; and service-endpoint-interface relates to @WebService.endpointInterface.
Prev 8.2. Create a web service starting from a Java source using JAX-WS. Up Home Next 9.2. Configure SOAP and logical handlers on the client side.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

9.2. Configure SOAP and logical handlers on the client side. Chapter 9. Create handlers for SOAP web services.

Next

9.2. Configure SOAP and logical handlers on the client side.


9.2.1. Use deployment descriptors.
The declarative configuration w orks for proxy clients only and w orks in the same w ay as for the endpoint example. That is, you simply add an annotation to the client-side generated SEI, w hich enables the handlers for all proxies and dispatch clients that are generated by using any ports on the SEI.

9.2.2. Use programmatic API.


The programmatic configuration w orks for all JAX-W S services, generated service interfaces, and the generic service. Handlers are added to the client-side service by using the follow ing method:

Service.setHandlerResolver(HandlerResolver handlerResolver);
Example below show s the HelloClientWithHandler class that programmatically adds the HelloMessengerProtocolHandler to the client-side SEI:

import import import import import import

HelloMessenger; HelloMessengerService; java.util.Collections; java.util.List; javax.xml.ws.handler.HandlerResolver; javax.xml.ws.handler.PortInfo;

public class HelloClientWithHandler { public static void main(String... args) throws Exception { HelloMessengerService service = new HelloMessengerService(); service.setHandlerResolver(new HandlerResolver() { public List getHandlerChain(PortInfo inf) { return Collections.singletonList(new HelloMessengerProtocolHandler()); } }); HelloMessenger port = service.getHelloMessengerPort(); String message = port.sayHello("Mikalai"); System.out.println(message); } }
The highlighted code show s the relevant handler configuration code. The application creates a new anonymous inner HandlerResolver that returns a singleton list that contains an instance of the HelloMessengerProtocolHandler. An advantage of the programmatic approach is that you are not required to change generated code.
Prev Chapter 9. Create handlers for SOAP web services. Up Home Next Chapter 10. Create low-level SOAP web services.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 10. Create low-level SOAP web services. Part I. Exam Objectives

Next

Chapter 10. Create low-level SOAP web services. 10.1. Describe the functions and capabilities of the APIs included within JAXP.
The Java API for XML Processing (JAXP) is for processing XML data using applications w ritten in the Java programming language. JAXP leverages the parser standards Simple API for XML Parsing (SAX) and Document Object Model (DOM) so that you can choose to parse your data as a stream of events or to build an object representation of it. JAXP also supports the Extensible Stylesheet Language Transformations (XSLT) standard, giving you control over the presentation of the data and enabling you to convert the data to other XML documents or to other formats, such as HTML. JAXP also provides namespace support, allow ing you to w ork w ith DTDs that might otherw ise have naming conflicts. Finally, as of version 1.4, JAXP implements the Streaming API for XML (StAX) standard. Designed to be flexible, JAXP allow s you to use any XML-compliant parser from w ithin your application. It does this w ith w hat is called a pluggability layer, w hich lets you plug in an implementation of the SAX or DOM API. The pluggability layer also allow s you to plug in an XSL processor, letting you control how your XML data is displayed. The main JAXP APIs are defined in the javax.xml.parsers package. That package contains vendor-neutral factory classes, SAXParserFactory, DocumentBuilderFactory, and TransformerFactory, w hich give you a SAXParser, a DocumentBuilder, and an XSLT transformer, respectively. DocumentBuilder, in turn, creates a DOM-compliant Document object. Simple API for XML APIs To start the process, an instance of the SAXParserFactory class is used to generate an instance of the SAXParser. Figure 10.1. SAX APIs

The parser w raps a SAXReader object. W hen the parser's parse() method is invoked, the reader invokes one of several callback methods implemented in the application. Those methods are defined by the interfaces ContentHandler, ErrorHandler, DTDHandler, and EntityResolver. Here is a summary of the key SAX APIs:

SAXParserFactory
A SAXParserFactory object creates an instance of the parser determined by the system property, javax.xml.parsers.SAXParserFactory.

SAXParser
The SAXParser interface defines several kinds of parse() methods. In general, you pass an XML data source and a DefaultHandler object to the parser, w hich processes the XML and invokes the appropriate methods in the handler object.

SAXReader
The SAXParser w raps a SAXReader. Typically, you do not care about that, but every once in a w hile you need to get hold of it using SAXParser's getXMLReader() so that you can configure it. It is the SAXReader that carries on the conversation w ith the SAX event handlers you define.

DefaultHandler
Not show n in the diagram, a DefaultHandler implements the ContentHandler, ErrorHandler, DTDHandler, and EntityResolver interfaces (w ith null methods), so you can override only the ones you are interested in.

ContentHandler
Methods such as startDocument, endDocument, startElement, and endElement are invoked w hen an XML tag is recognized. This interface also defines the methods characters() and processingInstruction(), w hich are invoked w hen the parser encounters the text in an XML element or an inline processing instruction, respectively.

ErrorHandler
Methods error(), fatalError(), and warning() are invoked in response to various parsing errors. The default error handler throw s an exception for fatal errors and ignores other errors (including validation errors). This is one reason you need to know something about the SAX parser, even if you are using the DOM. Sometimes, the application may be able to recover from a validation error. Other times, it may need to generate an exception. To ensure the correct handling, you w ill need to supply your ow n error handler to the parser.

DTDHandler
Defines methods you w ill generally never be called upon to use. Used w hen processing a DTD to recognize and act on declarations for an unparsed entity.

EntityResolver
The resolveEntity method is invoked w hen the parser must identify data identified by a URI. In most cases, a URI is simply a URL, w hich specifies the location of a document, but in some cases the document may be identified by a URN - a public identifier, or name, that is unique in the w eb space. The public identifier may be specified in addition to the URL. The EntityResolver can then use the public identifier instead of the URL to find the document - for example, to access a local copy of the document if one exists.

W hen to Use SAX


converted by Web2PDFConvert.com

W hen to Use SAX


SAX is fast and efficient, but its event model makes it most useful for state-independent filtering. For example, a SAX parser calls one method in your application w hen an element tag is encountered and calls a different method w hen text is found. If the processing you are doing is state-independent (meaning that it does not depend on the elements that have come before), then SAX w orks fine. On the other hand, for state-dependent processing, w here the program needs to do one thing w ith the data under element A but something different w ith the data under element B, then a pull parser such as the Streaming API for XML (StAX) w ould be a better choice. W ith a pull parser, you get the next node, w hatever it happens to be, at any point in the code that you ask for it. So it is easy to vary the w ay you process text (for example), because you can process it multiple places in the program. SAX requires much less memory than DOM, because SAX does not construct an internal representation (tree structure) of the XML data, as a DOM does. Instead, SAX simply sends data to the application as it is read; your application can then do w hatever it w ants to do w ith the data it sees. Pull parsers and the SAX API both act like a serial I/O stream. You see the data as it streams in, but you cannot go back to an earlier position or leap ahead to a different position. In general, such parsers w ork w ell w hen you simply w ant to read data and have the application act on it. But w hen you need to modify an XML structure - especially w hen you need to modify it interactively - an in-memory structure makes more sense. DOM is one such model. How ever, although DOM provides many pow erful capabilities for large-scale documents (like books and articles), it also requires a lot of complex coding. For simpler applications, that complexity may w ell be unnecessary. For faster development and simpler applications, one of the object-oriented XML-programming standards, such as JDOM (http://w w w .jdom.org) and DOM4J (http://dom4j.org/), might make more sense.

Parsing an XML File Using SAX


The follow ing code sets up the parser and gets it started:

static public void main(String[] args) throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); SAXParser saxParser = spf.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); xmlReader.setContentHandler(new MyHandler()); xmlReader.parse(fileURL); }
These lines of code create a SAXParserFactory instance, as determined by the setting of the javax.xml.parsers.SAXParserFactory system property. The factory to be created is set up to support XML namespaces by setting setNamespaceAware to true, and then a SAXParser instance is obtained from the factory by invoking its newSAXParser() method. Then you obtain an XMLReader instance for your parser by invoking your SAXParser instance's getXMLReader() method. The XMLReader then registers the MyHandler class as its content handler, so that the actions performed by the parser w ill be those of the startDocument(), startElement(), and endDocument(), etc methods. Finally, the XMLReader tells the parser w hich document to parse by passing it the location of the XML file in question, in the form of the file URL. The SAXParserFactory can be set up such that it uses a validating parser instead of the default non-validating parser:

SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); spf.setValidating(true); SAXParser saxParser = spf.newSAXParser();


Document Object Model APIs You use the javax.xml.parsers.DocumentBuilderFactory class to get a DocumentBuilder instance, and you use that instance to produce a Document object that conforms to the DOM specification. The builder you get, in fact, is determined by the system property javax.xml.parsers.DocumentBuilderFactory, w hich selects the factory implementation that is used to produce the builder. (The platform's default value can be overridden from the command line.) Figure 10.2. DOM APIs

You can also use the DocumentBuilder.newDocument() method to create an empty Document that implements the org.w3c.dom.Document interface. Alternatively, you can use one of the builder's parse methods to create a Document from existing XML data.

W hen to Use DOM


The Document Object Model standard is, above all, designed for documents (for example, articles and books). In addition, the JAXP 1.4.2 implementation supports XML Schema, something that can be an important consideration for any given application. On the other hand, if you are dealing w ith simple data structures and if XML Schema is not a big part of your plans, then you may find that one of the more object-oriented standards, such as JDOM or dom4j, is better suited for your purpose. From the start, DOM w as intended to be language-neutral. Because it w as designed for use w ith languages such as C and Perl, DOM does not take advantage of Java's objectoriented features. That fact, in addition to the distinction betw een documents and data, also helps to account for the w ays in w hich processing a DOM differs from processing a JDOM or dom4j structure.

Parsing an XML File Using DOM

converted by Web2PDFConvert.com

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setValidating(true; DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new File(filename));
Extensible Stylesheet Language Transformations APIs A TransformerFactory object is instantiated and used to create a Transformer. The source object is the input to the transformation process. A source object can be created from a SAX reader, from a DOM, or from an input stream. Figure 10.3. XSLT APIs

Similarly, the result object is the result of the transformation process. That object can be a SAX event handler, a DOM, or an output stream. W hen the transformer is created, it can be created from a set of transformation instructions, in w hich case the specified transformations are carried out. If it is created w ithout any specific instructions, then the transformer object simply copies the source to the result. Streaming API for XML APIs StAX is the latest API in the JAXP family, and provides an alternative to SAX, DOM, TrAX, and DOM for developers looking to do high-performance stream filtering, processing, and modification, particularly w ith low memory and limited extensibility requirements. To summarize, StAX provides a standard, bidirectional pull parser interface for streaming XML processing, offering a simpler programming model than SAX and more efficient memory management than DOM. StAX enables developers to parse and modify XML streams as events, and to extend XML information models to allow application-specific additions.

Comparing StAX to Other JAXP APIs


As an API in the JAXP family, StAX can be compared, among other APIs, to SAX, TrAX, and JDOM. Of the latter tw o, StAX is not as pow erful or flexible as TrAX or JDOM, but neither does it require as much memory or processor load to be useful, and StAX can, in many cases, outperform the DOM-based APIs. W ith this in mind, the closest comparisons can be made betw een StAX and SAX, and it is here that StAX offers features that are beneficial in many cases; some of these include: StAX-enabled clients are generally easier to code than SAX clients. W hile it can be argued that SAX parsers are marginally easier to w rite, StAX parser code can be smaller and the code necessary for the client to interact w ith the parser simpler. StAX is a bidirectional API, meaning that it can both read and w rite XML documents. SAX is read only, so another API is needed if you w ant to w rite XML documents. SAX is a push API, w hereas StAX is pull. Table 10.1. XML Parser API Feature Summary
Feature API Type Ease of Use XPath Capability CPU and Memory Efficiency Forward Only Read XML Write XML Create, Read, Update, Delete StAX Pull, streaming High No Good Yes Yes Yes No SAX Push, streaming Medium No Good Yes Yes No No DOM In memory tree High Yes Varies No Yes Yes Yes TrAX XSLT Rule Medium Yes Varies No Yes Yes No

The StAX API exposes methods for iterative, event-based processing of XML documents. XML documents are treated as a filtered series of events, and infoset states can be stored in a procedural fashion. Moreover, unlike SAX, the StAX API is bidirectional, enabling both reading and w riting of XML documents. The StAX API is really tw o distinct API sets: a cursor API and an iterator API.
converted by Web2PDFConvert.com

Cursor API
As the name implies, the StAX cursor API represents a cursor w ith w hich you can w alk an XML document from beginning to end. This cursor can point to one thing at a time, and alw ays moves forw ard, never backw ard, usually one infoset element at a time. The tw o main cursor interfaces are XMLStreamReader and XMLStreamWriter. XMLStreamReader includes accessor methods for all possible information retrievable from the XML Information model, including document encoding, element names, attributes, namespaces, text nodes, start tags, comments, processing instructions, document boundaries, and so forth; for example:

public interface XMLStreamReader { public int next() throws XMLStreamException; public boolean hasNext() throws XMLStreamException; public String getText(); public String getLocalName(); public String getNamespaceURI(); // ... other methods not shown }
You can call methods on XMLStreamReader, such as getText and getName, to get data at the current cursor location. XMLStreamWriter provides methods that correspond to StartElement and EndElement event types; for example:

public interface XMLStreamWriter { public void writeStartElement(String localName) throws XMLStreamException; public void writeEndElement() throws XMLStreamException; public void writeCharacters(String text) throws XMLStreamException; // ... other methods not shown }
The cursor API mirrors SAX in many w ays. For example, methods are available for directly accessing string and character information, and integer indexes can be used to access attribute and namespace information. As w ith SAX, the cursor API methods return XML information as strings, w hich minimizes object allocation requirements.

Iterator API
The StAX iterator API represents an XML document stream as a set of discrete event objects. These events are pulled by the application and provided by the parser in the order in w hich they are read in the source XML document. The base iterator interface is called XMLEvent, and there are subinterfaces for each event type. The primary parser interface for reading iterator events is XMLEventReader, and the primary interface for w riting iterator events is XMLEventWriter. The XMLEventReader interface contains five methods, the most important of w hich is nextEvent, w hich returns the next event in an XML stream. XMLEventReader implements java.util.Iterator, w hich means that returns from XMLEventReader can be cached or passed into routines that can w ork w ith the standard Java Iterator; for example:

public interface XMLEventReader extends Iterator { public XMLEvent nextEvent() throws XMLStreamException; public boolean hasNext(); public XMLEvent peek() throws XMLStreamException; ... }
Similarly, on the output side of the iterator API, you have:

public interface XMLEventWriter { public void flush() throws XMLStreamException; public void close() throws XMLStreamException; public void add(XMLEvent e) throws XMLStreamException; public void add(Attribute attribute) throws XMLStreamException; ... }
Comparing Cursor and Iterator APIs
Before choosing betw een the cursor and iterator APIs, you should note a few things that you can do w ith the iterator API that you cannot do w ith the cursor API: Objects created from the XMLEvent subclasses are immutable, and can be used in arrays, lists, and maps, and can be passed through your applications even after the parser has moved on to subsequent events. You can create subtypes of XMLEvent that are either completely new information items or extensions of existing items but w ith additional methods. You can add and remove events from an XML event stream in much simpler w ays than w ith the cursor API. Similarly, keep some general recommendations in mind w hen making your choice: If you are programming for a particularly memory-constrained environment, like Java ME, you can make smaller, more efficient code w ith the cursor API. If performance is your highest priority for example, w hen creating low -level libraries or infrastructure the cursor API is more efficient. If you w ant to create XML processing pipelines, use the iterator API. If you w ant to modify the event stream, use the iterator API. If you w ant your application to be able to handle pluggable processing of the event stream, use the iterator API. In general, if you do not have a strong preference one w ay or the other, using the iterator API is recommended because it is more flexible and extensible, thereby "future-proofing" your applications.
Prev 9.2. Configure SOAP and logical handlers on the client side. Up Next 10.2. Describe the functions and capabilities of JAXB, including the JAXB

converted by Web2PDFConvert.com

Home

process flow, such as XML-to-Java and Java-to-XML, and the binding and validation mechanisms provided by JAXB.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

10.2. Describe the functions and capabilities of JAXB, including the JAXB process flow, such as XML-to-Java and Java-to-XML, and the binding and validation mechanisms provided by JAXB. Prev Chapter 10. Create low-level SOAP web services. Next

10.2. Describe the functions and capabilities of JAXB, including the JAXB process flow, such as XML-to-Java and Java-to-XML, and the binding and validation mechanisms provided by JAXB.
The Java Architecture for XML Binding (JAXB) provides a fast and convenient w ay to bind betw een XML schemas and Java representations, making it easy for Java developers to incorporate XML data and processing functions in Java applications. As part of this process, JAXB provides methods for unmarshalling XML instance documents into Java content trees, and then marshalling Java content trees back into XML instance documents. JAXB also provides a w ay to generate XML schema from Java objects. Figure below show s the components that make up a JAXB implementation: Figure 10.4. JAXB Architectural Overview

A JAXB implementation consists of the follow ing architectural components: Schema compiler: Binds a source schema to a set of schema-derived program elements. The binding is described by an XML-based binding language. Schema generator: Maps a set of existing program elements to a derived schema. The mapping is described by program annotations. Binding runtime framew ork: Provides unmarshalling (reading) and marshalling (w riting) operations for accessing, manipulating, and validating XML content using either schema-derived or existing program elements. Figure below show s w hat occurs during the JAXB binding process: Figure 10.5. Steps in the JAXB Binding Process

The general steps in the JAXB data binding process are: 1. Generate classes: An XML schema is used as input to the JAXB binding compiler to generate JAXB classes based on that schema. 2. Compile classes: All of the generated classes, source files, and application code must be compiled. 3. Unmarshal: XML documents w ritten according to the constraints in the source schema are unmarshalled by the JAXB binding framew ork. Note that JAXB also supports unmarshalling XML data from sources other than files/documents, such as DOM nodes, string buffers, SAX Sources, and so forth. Unmarshalling provides a client application the ability to convert XML data into JAXB-derived Java objects. 4. Generate content tree: The unmarshalling process generates a content tree of data objects instantiated from the generated JAXB classes; this content tree represents the structure and content of the source XML documents. 5. Validate (optional): The unmarshalling process optionally involves validation of the source XML documents before generating the content tree. Note that if you modify the content tree in Step 6, below , you can also use the JAXB Validate operation to validate the changes before marshalling the content back to an XML document. 6. Process content: The client application can modify the XML data represented by the Java content tree by means of interfaces generated by the binding compiler. 7. Marshal: The processed content tree is marshalled out to one or more XML output documents. The content may be validated before marshalling. Marshalling provides a client application the ability to convert a JAXB-derived Java object tree back into XML data.

converted by Web2PDFConvert.com

Unmarshalling Generates content tree from XML document instance through JAXB binding framew ork. Sources for unmarshalling can be: Files/documents InputStream String buffers DOM nodes SAX Sources

javax.xml.bind.JAXBContext provides an abstraction (entry point to the JAXB API) for managing the XML/Java binding information necessary to implement the unmarshal,
marshal and validate operations.

javax.xml.bind.JAXBContext is created via newInstance(contextPath), w here contextPath contains a list of Java package names that contain schema derived
interfaces and classes.

JAXBContext jc = JAXBContext.newInstance("com.acme.foo:com.acme.bar");
Unmarshaller, Marshaller, Validator object are created from JAXBContext object. javax.xml.bind.Unmarshaller is a Java interface. It governs the process of deserializing XML data (XML document instance) into new ly created Java content tree,
optionally validates XML data as it is unmarshalled. Unmarshalling from a File:

// Create JAXBContext object JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); // Create Unmarshaller object Unmarshaller u = jc.createUnmarshaller(); // Unmarshall a XML document which is in the form of File Object o = u.unmarshal(new File("example.xml"));
Unmarshalling from an InputStream:

InputStream is = new FileInputStream("example.xml"); JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); Object o = u.unmarshal(is);


Unmarshalling from a URL:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); URL url = new URL("http://java.boot.by/example.xml"); Object o = u.unmarshal(url);
Unmarshalling from a StringBuffer:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); StringBuffer xmlStr = new StringBuffer("<?xml version="1.0"?>..."); Object o = u.unmarshal(new StreamSource(new StringReader(xmlStr.toString())));

Unmarshalling from a org.w3c.dom.Node:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new File("example.xml")); Object o = u.unmarshal(doc);
Unmarshalling from a javax.xml.transform.sax.SAXSource:

XMLReader xmlReader = saxParser.getXMLReader(); SAXSource source = new SAXSource( xmlReader, new InputSource( "http://..." ) );

converted by Web2PDFConvert.com

// Setup JAXB to unmarshal JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); ValidationEventCollector vec = new ValidationEventCollector(); u.setEventHandler(vec); // turn off the JAXB provider's default validation mechanism to // avoid duplicate validation u.setValidating(false); // unmarshal Object o = u.unmarshal(source);
Turning off validation during unmarshalling:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); u.setValidating(false); Object o = u.unmarshal(new File("example.xml"));


Marshalling Content tree may be marshalled by passing it to marshal method of Marshaller object, content trees are no longer required to be valid before marshalling.

javax.xml.bind.Marshaller is a Java interface, it governs the process of serializing Java content trees back into XML data.
Marshalling to a File:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); FooObject obj = (FooObject)u.unmarshal(new File("foo.xml")); Marshaller m = jc.createMarshaller(); OutputStream os = new FileOutputStream("newFoo.xml"); m.marshal(obj, os);
Marshalling to a SAX ContentHandler:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); FooObject obj = (FooObject)u.unmarshal(new File("foo.xml")); Marshaller m = jc.createMarshaller(); // assume MyContentHandler instanceof ContentHandler m.marshal(obj, new MyContentHandler());
Marshalling to a DOM Node:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); FooObject obj = (FooObject)u.unmarshal(new File("foo.xml")); Marshaller m = jc.createMarshaller(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.newDocument(); m.marshal(obj, doc);
Marshalling to a java.io.OutputStream:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); FooObject obj = (FooObject)u.unmarshal(new File("foo.xml")); Marshaller m = jc.createMarshaller(); m.marshal(obj, System.out);
Marshalling to a java.io.Writer:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); FooObject obj = (FooObject)u.unmarshal(new File("foo.xml"));


converted by Web2PDFConvert.com

Marshaller m = jc.createMarshaller(); m.marshal(obj, new PrintWriter(System.out));


Marshalling to a javax.xml.transform.SAXResult:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); FooObject obj = (FooObject)u.unmarshal(new File("foo.xml")); Marshaller m = jc.createMarshaller(); // assume MyContentHandler instanceof ContentHandler SAXResult result = new SAXResult(new MyContentHandler()); m.marshal(obj, result);
Marshalling to a javax.xml.transform.DOMResult:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); FooObject obj = (FooObject)u.unmarshal(new File("foo.xml")); Marshaller m = jc.createMarshaller(); DOMResult result = new DOMResult(); m.marshal(obj, result);
Marshalling to a javax.xml.transform.StreamResult:

JAXBContext jc = JAXBContext.newInstance("com.acme.foo"); Unmarshaller u = jc.createUnmarshaller(); FooObject obj = (FooObject)u.unmarshal(new File("foo.xml")); Marshaller m = jc.createMarshaller(); StreamResult result = new StreamResult(System.out); m.marshal(obj, result);
Validation Forms of validation: Fail-fast Validation: Simple runtime type constraint check that can be performed by property setter method. On-Demand Validation: Applications can call the Validator.validate method on the Java content tree (or any sub-tree of it):

JaxbContext jaxbCtx = JaxbContext.newInstance("generated.packageName"); Unmarshaller um = jaxbCtx.createUnmarshaller(); Trade trade = (Trade)um.unmarshal(inputStream); String symbol = trade.getSymbol(); float price = trace.getPrice(); if (symbol.equals("WIDGETS") && price > 10.00) { trade.setQuantity(30); } Validator validator = jaxbCtx.createValidator(); validator.validate(trade); Marshaller m = jaxbCtx.createMarshaller(); m.marshal(outputStream, trade);

Validation during Unmarshalling. Deprecated approach:

JAXBContext jc = JAXBContext.newInstance("by.boot.java"); // An Unmarshaller instance is created. Unmarshaller u = jc.createUnmarshaller(); // The default JAXB Unmarshaller ValidationEventHandler is enabled // to send to validation warnings and errors to System.out. The // default configuration causes the unmarshal operation to fail // upon encountering the first validation error. u.setValidating(true);
converted by Web2PDFConvert.com

Recommended approach:

JAXBContext jc = JAXBContext.newInstance("by.boot.java"); // An Unmarshaller instance is created. Unmarshaller u = jc.createUnmarshaller(); SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = sf.newSchema(new StreamSource(new File("schemaFile.xsd"))); // This sets us up for validation u.setSchema(schema);

Prev Chapter 10. Create low-level SOAP web services.

Up Home

Next 10.3. Use Provider API to create a web service.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

10.3. Use Provider API to create a web service. Chapter 10. Create low-level SOAP web services.

Next

10.3. Use Provider API to create a web service.


10.3.1. Process the entire SOAP message, using the SAAJ APIs.
SAAJ overview Although the SAAJ API can be used from JAX-W S applications, it can also be used alone. In fact, the SAAJ API contains all the classes that you need to send and receive SOAP messages. All the SAAJ classes belong to the javax.xml.soap package namespace. As show n in the figure below , the core SAAJ API exposes classes that closely mimic the actual SOAP messages structure: Figure 10.6. Core SAAJ 1.3 API

The core SAAJ API includes the follow ing classes and interfaces:

SOAPMessage
The SOAPMessage object represents the entire SOAP message. It has a single SOAPPart and possibly one or more AttachmentParts.

SOAPPart
The SOAPPart object contains a SOAPEnvelope message. The SOAPEnvelope represents the actual SOAP Envelope.

SOAPEnvelope
The SOAPEnvelope has an optional SOAPHeader and a mandatory SOAPBody.

SOAPHeader
The SOAPHeader represents the SOAP header block in a SOAP message and is allow ed to be empty as is the case w ith the header section in a SOAP 1.1 or 1.2 message.

SOAPBody
The SOAPBody element can contain either a SOAPFault object or the actual SOAP payload XML content ( SOAPBodyElement).

SOAPFault
The SOAPFault object represents a SOAP fault message. The SAAJ types and the types from the org.w3c.dom Java XML package are closely related. In fact, many of the classes in SAAJ extend or implement behavior from classes in the org.w3c.dom package namespace. An example of this is the SOAPPart object that implements the org.w3c.dom.Document interface. Accessing Elements of a Message There are tw o w ays to do this. First w ay:

SOAPPart soapPart = message.getSOAPPart(); SOAPEnvelope envelope = soapPart.getEnvelope(); SOAPHeader header = envelope.getHeader(); SOAPBody body = envelope.getBody();
Second w ay:

SOAPHeader header = message.getSOAPHeader();

converted by Web2PDFConvert.com

SOAPBody body = message.getSOAPBody();


Adding Content to the Body The SOAPBody object contains either content or a fault. To add content to the body, you normally create one or more SOAPBodyElement objects to hold the content. You can also add subelements to the SOAPBodyElement objects by using the addChildElement method. For each element or child element, you add content by using the addTextNode method. W hen you create any new element, you also need to create an associated javax.xml.namespace.QName object so that it is uniquely identified.

QName objects associated w ith SOAPBodyElement or SOAPHeaderElement objects must be fully qualified; that is, they must be created w ith a namespace URI, a local part,
and a namespace prefix. Specifying a namespace for an element makes clear w hich one is meant if more than one element has the same local name. The follow ing code fragment retrieves the SOAPBody object body from message, constructs a QName object for the element to be added, and adds a new SOAPBodyElement object to body:

SOAPBody body = message.getSOAPBody(); QName bodyName = new QName("http://wombat.ztrade.com", "GetLastTradePrice", "m"); SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
At this point, body contains a SOAPBodyElement object identified by the QName object bodyName, but there is still no content in bodyElement. Assuming that you w ant to get a quote for the stock of Sun Microsystems, Inc., you need to create a child element for the symbol using the addChildElement method. Then you need to give it the stock symbol using the addTextNode method. The QName object for the new SOAPElement object symbol is initialized w ith only a local name because child elements inherit the prefix and URI from the parent element:

QName name = new QName("symbol"); SOAPElement symbol = bodyElement.addChildElement(name); symbol.addTextNode("SUNW");


You might recall that the headers and content in a SOAPPart object must be in XML format. The SAAJ API takes care of this for you, building the appropriate XML constructs automatically w hen you call methods such as addBodyElement, addChildElement, and addTextNode. Note that you can call the method addTextNode only on an element such as bodyElement or any child elements that are added to it. You cannot call addTextNode on a SOAPHeader or SOAPBody object because they contain elements and not text. The content that you have just added to your SOAPBody object w ill look like the follow ing:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> <m:GetLastTradePrice xmlns:m="http://wombat.ztrade.com"> <symbol>SUNW</symbol> </m:GetLastTradePrice> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

Getting the Content of a Message The initial steps for retrieving a message's content are the same as those for giving content to a message: Either you use the SOAPMessage object to get the SOAPBody object, or you access the SOAPBody object through the SOAPPart and SOAPEnvelope objects. Then you access the SOAPBody object's SOAPBodyElement object, because that is the element to w hich content w as added in the example. To get the content, w hich w as added w ith the method SOAPElement.addTextNode, you call the method Node.getValue. Note that getValue returns the value of the immediate child of the element that calls the method. Therefore, in the follow ing code fragment, the getValue method is called on bodyElement, the element on w hich the addTextNode method w as called. To access bodyElement, you call the getChildElements method on soapBody. Passing bodyName to getChildElements returns a java.util.Iterator object that contains all the child elements identified by the Name object bodyName. You already know that there is only one, so calling the next method on it w ill return the SOAPBodyElement you w ant. Note that the Iterator.next() method returns a Java Object, so you need to cast the Object it returns to a SOAPBodyElement object before assigning it to the variable bodyElement:

SOAPBody soapBody = response.getSOAPBody(); QName bodyName = new QName("http://wombat.ztrade.com", "GetLastTradePrice", "m"); java.util.Iterator iterator = soapBody.getChildElements(bodyName); SOAPBodyElement bodyElement = (SOAPBodyElement)iterator.next(); String lastPrice = bodyElement.getValue();
Adding Content to the Header To add content to the header, you create a SOAPHeaderElement object. As w ith all new elements, it must have an associated QName object. For example, suppose you w ant to add a conformance claim header to the message to state that your message conforms to the W S-I Basic Profile. The follow ing code fragment retrieves the SOAPHeader object from message and adds a new SOAPHeaderElement object to it. This SOAPHeaderElement object contains the correct qualified name and attribute for a W S-I conformance claim header:

SOAPHeader header = message.getSOAPHeader(); QName headerName = new QName("http://ws-i.org/schemas/conformanceClaim/", "Claim", "wsi"); SOAPHeaderElement headerElement = header.addHeaderElement(headerName); headerElement.addAttribute(new QName("conformsTo"), "http://ws-i.org/profiles/basic/1.1/");
At this point, header contains the SOAPHeaderElement object headerElement identified by the QName object headerName. Note that the addHeaderElement method

converted by Web2PDFConvert.com

both creates headerElement and adds it to header. A conformance claim header has no content. This code produces the follow ing XML header:

<SOAP-ENV:Header> <wsi:Claim xmlns:wsi="http://ws-i.org/schemas/conformanceClaim/" conformsTo="http://ws-i.org/profiles/basic/1.1/"/> </SOAP-ENV:Header>

For a different kind of header, you might w ant to add content to headerElement. The follow ing line of code uses the method addTextNode to do this:

headerElement.addTextNode("order");
Creating an AttachmentPart Object and Adding Content The SOAPMessage object creates an AttachmentPart object, and the message also must add the attachment to itself after content has been added. The SOAPMessage class has three methods for creating an AttachmentPart object. The first method creates an attachment w ith no content. In this case, an AttachmentPart method is used later to add content to the attachment:

AttachmentPart attachment = message.createAttachmentPart();


You add content to attachment by using the AttachmentPart method setContent. This method takes tw o parameters: a Java Object for the content, and a String object for the MIME content type that is used to encode the object. Content in the SOAPBody part of a message automatically has a Content-Type header w ith the value "text/xml" because the content must be in XML. In contrast, the type of content in an AttachmentPart object must be specified because it can be any type. Each AttachmentPart object has one or more MIME headers associated w ith it. W hen you specify a type to the setContent method, that type is used for the header Content-Type. Note that Content-Type is the only header that is required. You may set other optional headers, such as Content-Id and Content-Location. For convenience, SAAJ provides get and set methods for the headers Content-Type, Content-Id, and Content-Location. These headers can be helpful in accessing a particular attachment w hen a message has multiple attachments. For example, to access the attachments that have particular headers, you can call the SOAPMessage method getAttachments and pass it a MIMEHeaders object containing the MIME headers you are interested in. The follow ing code fragment show s one of the w ays to use the method setContent. The Java Object in the first parameter can be a String, a stream, a javax.xml.transform.Source object, or a javax.activation.DataHandler object. The Java Object being added in the follow ing code fragment is a String, w hich is plain text, so the second argument must be "text/plain". The code also sets a content identifier, w hich can be used to identify this AttachmentPart object. After you have added content to attachment, you must add it to the SOAPMessage object:

String stringContent = "10 Upbeat Street, Pleasant Grove, CA 95439"; attachment.setContent(stringContent, "text/plain"); attachment.setContentId("update_address"); message.addAttachmentPart(attachment);
The other tw o SOAPMessage.createAttachment methods create an AttachmentPart object complete w ith content. One is very similar to the AttachmentPart.setContent method in that it takes the same parameters and does essentially the same thing. It takes a Java Object containing the content and a String giving the content type. As w ith AttachmentPart.setContent, the Object can be a String, a stream, a javax.xml.transform.Source object, or a javax.activation.DataHandler object. The other method for creating an AttachmentPart object w ith content takes a DataHandler object, w hich is part of the JavaBeans Activation Framew ork (JAF). Using a DataHandler object is fairly straightforw ard. First, you create a java.net.URL object for the file you w ant to add as content. Then you create a DataHandler object initialized w ith the URL object:

URL url = new URL("http://java.boot.by/img.jpg"); DataHandler dataHandler = new DataHandler(url); AttachmentPart attachment = message.createAttachmentPart(dataHandler); attachment.setContentId("attached_image"); message.addAttachmentPart(attachment);
You might note tw o things about this code fragment. First, it sets a header for Content-ID using the method setContentId. This method takes a String that can be w hatever you like to identify the attachment. Second, unlike the other methods for setting content, this one does not take a String for Content-Type. This method takes care of setting the Content-Type header for you, something that is possible because one of the things a DataHandler object does is to determine the data type of the file it contains. Accessing an AttachmentPart Object If you receive a message w ith attachments or w ant to change an attachment to a message you are building, you need to access the attachment. The SOAPMessage class provides tw o versions of the getAttachments method for retrieving its AttachmentPart objects. W hen it is given no argument, the method SOAPMessage.getAttachments() returns a java.util.Iterator object over all the AttachmentPart objects in a message. W hen getAttachments is given a MimeHeaders object, w hich is a list of MIME headers, getAttachments returns an iterator over the AttachmentPart objects that have a header that matches one of the headers in the list. The follow ing code uses the getAttachments method that takes no arguments and thus retrieves all the AttachmentPart objects in the SOAPMessage object message. Then it prints the content ID, the content type, and the content of each AttachmentPart object:

java.util.Iterator iterator = message.getAttachments(); while (iterator.hasNext()) { AttachmentPart attachment = (AttachmentPart)iterator.next(); String id = attachment.getContentId(); String type = attachment.getContentType(); System.out.print("Attachment " + id + " has content type " + type);
converted by Web2PDFConvert.com

if (type.equals("text/plain")) { Object content = attachment.getContent(); System.out.println("Attachment contains:\n" + content); } }

10.3.2. Process only the SOAP body, using JAXB.


Developing a dispatch client that uses JAXB Example below demonstrates how JAX-W S allow s you to w ork w ith JAXB objects from a dispatch client:

import import import import import import import import import

by.boot.java.ObjectFactory; by.boot.java.SayHello; by.boot.java.SayHelloResponse; javax.xml.bind.JAXBContext; javax.xml.bind.JAXBElement; javax.xml.namespace.QName; javax.xml.ws.Dispatch; javax.xml.ws.Service; javax.xml.ws.soap.SOAPBinding;

public class HelloJaxbClient { private static final String TNS = "http://java.boot.by/"; public static void main(String... args) throws Exception { // Define the service name, port name, and endpoint address QName serviceName = new QName(TNS, "HelloMessengerService"); QName portName = new QName(TNS, "HelloMessenger"); String endpoint = "http://localhost:80/Hello"; // Create a service that can bind to the HelloMessenger port Service service = Service.create(serviceName); service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpoint); // Create a JAXB enabled Dynamic Dispatch client JAXBContext context = JAXBContext.newInstance("by.boot.java"); Dispatch<Object> dispatch = service.createDispatch(portName, context, Service.Mode.PAYLOAD); // Create JAXB request object ObjectFactory objectFactory = new ObjectFactory(); SayHello request = objectFactory.createSayHello(); request.setArg0("Mikalai"); JAXBElement<SayHello> requestMessage = objectFactory.createSayHello(request); // Invoke the HelloMessenger Web service JAXBElement<SayHelloResponse> responseMessage = (JAXBElement<SayHelloResponse>)dispatch.invoke(requestMessage); // Get the JAXB response SayHelloResponse response = responseMessage.getValue(); String value = response.getReturn(); // Print the response System.out.println(value); } }
The lines in bold illustrate w here JAXB functionality is being used. The key point to note w ith regards to the dispatch client creation is that the Service.createDispatch method is invoked w ith a JAXBContext and a PAYLOAD service mode. The PAYLOAD argument specifies to the JAX-W S run time that it should take care of handling the SOAP envelope details. The JAXBContext argument specifies that w e w ill let JAXB handle the marshalling and unmarshalling of the actual SOAP payload. After creation of the dispatch client, the application demonstrates how the generated ObjectFactory class is used to produce the request objects that w ill be sent over the w ire. Since the generated classes ( SayHello and SayHelloResponse) in this example have not been annotated w ith a @XmlRootElement by the JAXB binding compiler, JAXB requires that they be w rapped in a JAXBElement w rapper. Developing a JAX-WS logical handler that uses JAXB JAXB w orks w ell w ith logical handlers that are unaw are of the actual transport protocol details. Example below demonstrates a logical JAX-W S handler that transforms outgoing payload text to uppercase:

import import import import import import

javax.xml.bind.JAXBContext; javax.xml.bind.JAXBException; javax.xml.ws.LogicalMessage; javax.xml.ws.handler.LogicalHandler; javax.xml.ws.handler.LogicalMessageContext; javax.xml.ws.handler.MessageContext;

public class UppercaseMessageHandler implements LogicalHandler<LogicalMessageContext> {

converted by Web2PDFConvert.com

public boolean handleMessage(LogicalMessageContext ctx) { String outboundProp = MessageContext.MESSAGE_OUTBOUND_PROPERTY; boolean outbound = (Boolean) ctx.get(outboundProp); if (outbound) { try { LogicalMessage message = ctx.getMessage(); JAXBContext context = JAXBContext.newInstance(SayHelloResponse.class); SayHelloResponse response = (SayHelloResponse) message.getPayload(context); response.setReturn(response.getReturn().toUpperCase()); message.setPayload(response, context); } catch (JAXBException e) { e.printStackTrace(); } } return true /* continue chain */; } public void close(MessageContext ctx) {} public boolean handleFault(LogicalMessageContext ctx) { return false; } }
The lines that involve JAXB are highlighted in bold. The handler checks w hether the current message being handled is outbound or inbound. If the message is outbound, it gets the JAXB payload object from the LogicalMessage, updates the return value to uppercase, and overrides the entire payload. The SayHelloResponse object in this example w as generated w ith an @XmlRootElement annotation. Therefore, w e did not need to be concerned w ith the JAXBElement w rapper.
Prev 10.2. Describe the functions and capabilities of JAXB, including the JAXB process flow, such as XML-to-Java and Java-to-XML, and the binding and validation mechanisms provided by JAXB. Up Home Next 10.4. Use Dispatch API to create a dynamic web service client.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

10.4. Use Dispatch API to create a dynamic web service client. Chapter 10. Create low-level SOAP web services.

Next

10.4. Use Dispatch API to create a dynamic web service client.


XML w eb services use XML messages for communication betw een services and service clients. The higher level JAX-W S APIs are designed to hide the details of converting betw een Java method invocations and the corresponding XML messages, but in some cases operating at the XML message level is desirable. The javax.xml.ws.Dispatch interface provides support for this mode of interaction.

Dispatch supports tw o usage modes, identified by the constants javax.xml.ws.Service.Mode.MESSAGE and javax.xml.ws.Service.Mode.PAYLOAD respectively: javax.xml.ws.Service.Mode.MESSAGE: In this mode, client applications w ork directly w ith protocol-specific message structures. E.g., w hen used w ith a SOAP
protocol binding, a client application w ould w ork directly w ith a SOAP message.

javax.xml.ws.Service.Mode.PAYLOAD: In this mode, client applications w ork w ith the payload of messages rather than the messages themselves. E.g., w hen used w ith a SOAP protocol binding, a client application w ould w ork w ith the contents of the SOAP Body rather than the SOAP message as a w hole. Dispatch is a low level API that requires clients to construct messages or message payloads as XML and requires an intimate know ledge of the desired message or payload structure. Dispatch is a generic interface that supports input and output of messages or message payloads of any type. Implementations are required to support the
follow ing types of object:

javax.xml.transform.Source
Use of Source objects allow s clients to use XML generating and consuming APIs directly. Source objects may be used w ith any protocol binding in either message or message payload mode. W hen used w ith the HTTP binding in payload mode, the HTTP request and response entity bodies must contain XML directly or a MIME w rapper w ith an XML root part. A null value for Source is allow ed to make it possible to invoke an HTTP GET method in the HTTP Binding case. A WebServiceException MUST be throw n w hen a Dispatch<Source> is invoked and the Service returns a MIME message. W hen used in message mode, if the message is not an XML message a WebServiceException MUST be throw n. JAXB Objects Use of JAXB allow s clients to use JAXB objects generated from an XML Schema to create and manipulate XML representations and to use these objects w ith JAX-W S w ithout requiring an intermediate XML serialization. JAXB objects may be used w ith any protocol binding in either message or message payload mode. W hen used w ith the HTTP binding in payload mode, the HTTP request and response entity bodies must contain XML directly or a MIME w rapper w ith an XML root part. W hen used in mssage mode, if the message is not an XML message a WebServiceException MUST be throw n.

Service provides a createDispatch factory method for creating Dispatch instances that contain an embedded JAXBContext. The context parameter contains the JAXBContext instance that the created Dispatch instance w ill use to marshall and unmarshall messages or message payloads. javax.xml.soap.SOAPMessage
Use of SOAPMessage objects allow s clients to w ork w ith SOAP messages using the convenience features provided by the java.xml.soap package. SOAPMessage objects may only be used w ith Dispatch instances that use the SOAP binding in message mode.

javax.activation.DataSource
Use of DataSource objects allow s clients to w ork w ith MIME-typed messages. DataSource objects may only be used w ith Dispatch instances that use the HTTP binding in message mode.

Dispatch instances are obtained using the createDispatch factory methods of a Service instance. The mode parameter of createDispatch controls w hether the new Dispatch instance is message or message payload oriented. The type parameter controls the type of object used for messages or message payloads. Dispatch instances are
not thread safe.

Dispatch instances are not required to be dynamically configurable for different protocol bindings; the W SDL binding from w hich the Dispatch instance is generated contains static information including the protocol binding and service endpoint address. How ever, a Dispatch instance may support configuration of certain aspects of its operation and provides methods (inherited from BindingProvider) to dynamically query and change the values of properties in its request and response contexts.
A Dispatch instance supports three invocation modes: Synchronous request response ( invoke methods) The method blocks until the remote operation completes and the results are returned. Asynchronous request response ( invokeAsync methods) The method returns immediately, any results are provided either through a callback or via a polling object. One-w ay ( invokeOneWay methods) The method is logically non-blocking, subject to the capabilities of the underlying protocol, no results are returned.

Dispatch supports tw o forms of asynchronous invocation:


Polling The invokeAsync method returns a Response that may be polled using the methods inherited from Future<T> to determine w hen the operation has completed and to retrieve the results. Callback The client supplies an AsyncHandler and the runtime calls the handleResponse method w hen the results of the operation are available. The invokeAsync method returns a w ildcard Future ( Future<?>) that may be polled to determine w hen the operation has completed. The object returned from Future<?>.get() has no standard type. Client code should not attempt to cast the object to any particular type as this w ill result in non-portable behavior. The follow ing interfaces are used to obtain the results of an operation invocation:

javax.xml.ws.Response
A generic interface that is used to group the results of an invocation w ith the response context. Response extends java.util.concurrent.Future<T> to provide asynchronous result polling capabilities.

javax.xml.ws.AsyncHandler
A generic interface that clients implement to receive results in an asynchronous callback. It defines a single handleResponse method that has a Response object as its argument. The follow ing examples demonstrate use of Dispatch methods in the synchronous, asynchronous polling, and asynchronous callback modes:

converted by Web2PDFConvert.com

Synchronous, Payload-Oriented:

Source reqMsg = ...; Service service = ...; Dispatch<Source> disp = service.createDispatch(portName, Source.class, PAYLOAD); Source resMsg = disp.invoke(reqMsg);

Synchronous, Message-Oriented:

SOAPMessage soapReqMsg = ...; Service service = ...; Dispatch<SOAPMessage> disp = service.createDispatch(portName, SOAPMessage.class, MESSAGE); SOAPMessage soapResMsg = disp.invoke(soapReqMsg);

Synchronous, Payload-Oriented W ith JAXB Objects:

JAXBContext jc = JAXBContext.newInstance("primer.po"); Unmarshaller u = jc.createUnmarshaller(); PurchaseOrder po = (PurchaseOrder)u.unmarshal(new FileInputStream("po.xml")); Service service = ...; Dispatch<Object> disp = service.createDispatch(portName, jc, PAYLOAD); OrderConfirmation conf = (OrderConfirmation)disp.invoke(po);

In the above example PurchaseOrder and OrderConfirmation are interfaces pre-generated by JAXB from the schema document ' primer.po'. Asynchronous, Polling, Message-Oriented:

SOAPMessage soapReqMsg = ...; Service service = ...; Dispatch<SOAPMessage> disp = service.createDispatch(portName, SOAPMessage.class, MESSAGE); Response<SOAPMessage> res = disp.invokeAsync(soapReqMsg); while (!res.isDone()) { // do something while we wait } SOAPMessage soapResMsg = res.get();

Asynchronous, Callback, Payload-Oriented:

class MyHandler implements AsyncHandler<Source> { ... public void handleResponse(Response<Source> res) { Source resMsg = res.get(); // do something with the results } } Source reqMsg = ...; Service service = ...; Dispatch<Source> disp = service.createDispatch(portName, Source.class, PAYLOAD); MyHandler handler = new MyHandler(); disp.invokeAsync(reqMsg, handler);

Configuring the client BindingProviders Both proxy-based clients and dispatch-based clients share a common configuration model. The configuration is performed programmatically in the context of the Java w eb service client code. By using this configuration, you can specify an explicit endpoint location, HTTP protocol session behavior, HTTP authentication credentials, and more. The actual programmatic configuration is performed on the javax.xml.ws.BindingProvider client-side object. The dynamic proxies that are generated by the JAX-W S run time implement the javax.xml.ws.BindingProvider interface, w here the Dispatch interface extends it. Therefore, dispatch objects produced by the JAX-W S Service class, by contract, also implement the BindingProvider behavior. To configure the client BindingProvider, you add information to the request context, w hich is an ordinary java.util.Map<String, Object> that contains the actual configuration. The keys are strings and the values are objects. The map is available by using the BindingProvider.getRequestContext() method. JAX-W S 2.1 specifies the follow ing standard properties that can be used to configure the request context:

javax.xml.ws.service.endpoint.adress (value type: String)


Specifies the w eb service endpoint address.

javax.xml.ws.security.auth.username (value type: String)

converted by Web2PDFConvert.com

Specifies the user name in a set of HTTP basic authentication credentials.

javax.xml.ws.security.auth.password (value type: String)


Specifies the passw ord in a set of HTTP basic authentication credentials.

javax.xml.ws.session.maintain (value type: Boolean, default: false)


Specifies w hether the client is w illing to participate in a server-initiated session. Example below show s how to allow the w eb service client to participate in w eb service endpoint initiated sessions:

import import import import public

java.util.Map; by.boot.java.HelloMessenger; by.boot.java.HelloMessengerService; javax.xml.ws.BindingProvider; class HelloClientHttpSession {

public static void main(String... args) throws Exception { // Obtain the dynamic stub from the Service HelloMessengerService service = new HelloMessengerService(); HelloMessenger proxy = service.getHelloMessengerPort(); // Cast the proxy to a BindingProvider BindingProvider bindingProvider = (BindingProvider) proxy; // Get the request context Map<String, Object> requestContext = bindingProvider.getRequestContext(); // Configure session preference requestContext.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true); // Perform Web service method invocation and print the result String message = proxy.sayHello("Mikalai"); System.out.println(message); } }

Prev 10.3. Use Provider API to create a web service.

Up Home

Next Chapter 11. Use MTOM and MIME in a SOAP web service.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 11. Use MTOM and MIME in a SOAP web service. Part I. Exam Objectives

Next

Chapter 11. Use MTOM and MIME in a SOAP web service. 11.1. Use MTOM on the service.
11.1.1. Use @MTOM annotation with a web service.
javax.xml.ws.soap.MTOM @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @WebServiceFeatureAnnotation(id=MTOMFeature.ID,bean=MTOMFeature.class) public @interface MTOM { /** * Specifies if this feature is enabled or disabled. */ boolean enabled() default true; /** * Property for MTOM threshold value. When MTOM is enabled, binary data above this * size in bytes will be XOP encoded or sent as attachment. The value of this property * MUST always be >= 0. Default value is 0. */ int threshold() default 0; }

W ith Java API for XML-Based Web Services (JAX-W S), you can send binary attachments such as images or files along w ith w eb services requests. JAX-W S adds support for optimized transmission of binary data as specified by the SOAP Message Transmission Optimization Mechanism (MTOM) specification. JAX-W S supports the use of SOAP Message Transmission Optimized Mechanism (MTOM) for sending binary attachment data. By enabling MTOM, you can send and receive binary data optimally w ithout incurring the cost of data encoding needed to embed the binary data in an XML document. JAX-W S applications can send binary data as base64 or hexBinary encoded data contained w ithin the XML document. How ever, to take advantage of the optimizations provided by MTOM, enable MTOM to send binary base64 data as attachments contained outside the XML document. MTOM optimization is not enabled by default. JAX-W S applications require separate configuration of both the client and the server artifacts to enable MTOM support. For the server, you can enable MTOM on a JavaBean endpoint only and not on endpoints that implement the javax.xml.ws.Provider interface. Procedure: 1. Develop Java artifacts for your JAX-W S application that includes an XML schema or Web Services Description Language (W SDL) file that represents your w eb services application data that includes a binary attachment. a. If you are starting w ith a W SDL file, develop Java artifacts from a W SDL file by using the wsimport command to generate the required JAX-W S portable artifacts. b. If you are starting w ith JavaBeans components, develop Java artifacts for JAX-W S applications and optionally generate a W SDL file using the wsgen command. The XML schema or W SDL file includes a xsd:base64Binary or xsd:hexBinary element definition for the binary data. c. You can also include the xmime:expectedContentTypes attribute on the element to affect the mapping by JAXB. 2. Enable MTOM on a JavaBean endpoint. To enable MTOM on an endpoint, use the @MTOM ( javax.xml.ws.soap.MTOM) annotation on the endpoint. The @MTOM annotation has tw o parameters: enabled and threshold. The enabled parameter has a boolean value and indicates if MTOM is enabled for the JAX-W S endpoint. The threshold parameter has an integer value, and it specifies the minimum size for messages that are sent using MTOM. W hen the message size is less than this specified integer, the message is inlined in the XML document as base64 or hexBinary data. To enable MTOM in the w eb service, specify the @java.xml.ws.soap.MTOM annotation on the service endpoint implementation class, as illustrated in the follow ing example. Relevant code is show n in bold:

package examples.webservices.mtom; import javax.jws.WebMethod; import javax.jws.WebService; import javax.xml.ws.soap.MTOM; @MTOM @WebService(name="MtomPortType", serviceName="MtomService", targetNamespace="http://example.org") public class MTOMImpl { @WebMethod public String echoBinaryAsString(byte[] bytes) { return new String(bytes); } }
Additionally, you can use the @BindingType ( javax.xml.ws.BindingType) annotation on a server endpoint implementation class to specify that the endpoint supports one of the MTOM binding types so that the response messages are MTOM-enabled. The javax.xml.ws.SOAPBinding class defines tw o different constants, SOAP11HTTP_MTOM_BINDING and SOAP12HTTP_MTOM_BINDING that you can use for the value of the @BindingType annotation.

// for SOAP version 1.1 @BindingType(value = SOAPBinding.SOAP11HTTP_MTOM_BINDING) // for SOAP version 1.2 @BindingType(value = SOAPBinding.SOAP12HTTP_MTOM_BINDING)

converted by Web2PDFConvert.com

11.1.2. Use MTOM policy in WSDL.


Follow ing W SDL example demonstrates use of the Optimized Mime Serialization policy assertion:

1 <wsdl:definitions 2 targetNamespace="example.com" 3 xmlns:tns="example.com" 4 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 5 xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" 6 xmlns:wsoma="http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization" 7 xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" > 8 <wsp:Policy wsu:Id="MyPolicy" > 9 <wsoma:OptimizedMimeSerialization /> 10 <!-- omitted assertions --> 11 </wsp:Policy> 12 <!-- omitted elements --> 13 <wsdl:binding name="MyBinding" type="tns:MyPortType" > 14 <wsp:PolicyReference 15 URI="#MyPolicy" 16 wsdl:required="true" /> 17 <!-- omitted elements --> 18 </wsdl:binding> 19 </wsdl:definitions>
Lines (8-11) in are a policy expression that includes an Optimized Mime Serialization policy assertion (Line 9) to indicate that the SOAP Message Transmission Optimization Mechanism (MTOM) may be used. Lines (13-18) are a W SDL binding. Lines (14-16) indicate that the policy in Lines (8-11) applies to this binding, specifically indicating that MTOM encodings must be accepted over all the messages in the binding. Line (16) indicates policy is a required extension. MTOM is used to optimize the transmission of SOAP message over the w ire. MTOM uses a w ire format of a SOAP message by selectively encoding portions of the message, w hilst still presenting an XML Infoset to the SOAP application. Optimization is available only for element content that is in a canonical lexical representation of the xs:base64Binary data type. Message Part: Consider a message w ith one of it part as base64Binary:

<message name="mtomOperationRequest"> <part name="part1" type="xsd:string"/> <part name="part2" type="xsd:base64Binary"/> </message>

Binding: it show s how the binding use the MTOM policy:

<binding name="mtomBinding" type="tns:mtomPortType"> <wsp:PolicyReference URI="#mtomBindingPolicy"/> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="mtomOperation"> <soap:operation/> <input name="input1"> <soap:body use="literal" namespace="http://j2ee.netbeans.org/wsdl/mtomBP/mtom"/> </input> ... </binding>

MTOM policy:

<wsp:Policy wsu:Id="mtomBindingPolicy"> <wsp:ExactlyOne> <wsp:All> <wsoma:OptimizedMimeSerialization/> </wsp:All> </wsp:ExactlyOne> </wsp:Policy>

The w ire format below show how the SOAP envelope is transmitted using HTTP, take a note of the part2 w hich represent the binary data and how the data is trasmitted, note the data is not part of the SOAP envelope, instead it is transmitted as a separate MIME part:

POST /mtomService/mtomPort HTTP/1.1 SOAPAction: "" Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Content-Type: multipart/related; start="<rootpart*b0ef6adc-44fa-47ba-a7a7-95915eb54d9e@example.jaxws.sun.com>"; type="application/xop+xml"; boundary="uuid:b0ef6adc-44fa-47ba-a7a7-95915eb54d9e"; start-info="text/xml" User-Agent: JAX-WS RI 2.1.4.1-hudson-346Host: localhost:9088 Connection: keep-alive Content-Length: 890 --uuid:b0ef6adc-44fa-47ba-a7a7-95915eb54d9e Content-Id: <rootpart*b0ef6adc-44fa-47ba-a7a7-95915eb54d9e@example.jaxws.sun.com> Content-Type: application/xop+xml;charset=utf-8;type="text/xml"

converted by Web2PDFConvert.com

Content-Transfer-Encoding: binary <?xml version='1.0' encoding='UTF-8'?> <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <ns2:mtomOperation xmlns:ns2="http://j2ee.netbeans.org/wsdl/mtomBP/mtom"> <part1>hello</part1> <part2> <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:2f3a859b-6cdb-4eba-8163-0365521f094c@example.jaxws.sun.com" /> </part2> </ns2:mtomOperation> </S:Body> </S:Envelope> --uuid:b0ef6adc-44fa-47ba-a7a7-95915eb54d9e Content-Id: <2f3a859b-6cdb-4eba-8163-0365521f094c@example.jaxws.sun.com> Content-Type: application/octet-stream Content-Transfer-Encoding: binary [BINARY ATTACHMENT] --uuid:b0ef6adc-44fa-47ba-a7a7-95915eb54d9e--

Some of the points to note in the above w ire format example are: The binary attachment is packaged in a MIME multi-part message. An <xop:Include> element is used to mark w here the binary data is. The actual binary data is kept in a different MIME part. If binary data is sent as inlined, then the runtime has to encode the data to xs:base64Binary, w hich bloats the data by 33%, MTOM is efficient, in the sense that it doesn't have the 33% size increase penalty that xs:base64Binary has. It is interoperable, in the sense that it is a W 3C standard. How ever, MIME multipart incurs a small cost proportional to the number of attachments, so it is not suitable for a large number of tiny attachments. One can control the behavior of the runtime by using the MTOM threshold provided by the JAX-W S RI, if an attachment is smaller than the size specified in threshold, it w ill simply inline the binary data as BASE64 binary instead of making it an attachment.

11.1.3. Use MTOM in the deployment descriptors


You can enable MTOM on server by using the enable-mtom attribute in the sun-jaxws.xml configuration file. This allow s the MTOM setting to be changed at deployment time:

<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'> <endpoint name="Mtom" implementation="mtom.server.HelloImpl" url-pattern="/hello" enable-mtom="true"/> </endpoints>

11.1.4. Use MTOMFeature with javax.xml.ws.Endpoint API


javax.xml.ws.soap.MTOMFeature
The MTOMFeature is used to specify if MTOM should be used w ith a w eb service. This feature should be used instead of the javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING, javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_MTOM_BINDING and the javax.xml.ws.soap.SOAPBinding.setMTOMEnabled(). This feature MUST be supported w ith the SOAP 1.1/HTTP or SOAP 1.2/HTTP bindings. Using this feature w ith any other bindings is undened. This feature corresponds to the @MTOM annotation. Enabling this feature on either the server or client w ill result the JAX-W S runtime using MTOM and for binary data being sent as an attachment. The MTOMFeature has one property threshold, that can be configured to serve as a hint for w hich binary data SHOULD be sent as an attachment. The threshold is the size in bytes that binary data SHOULD be in order to be sent as an attachment. The threshold MUST not be negative. The default value is 0.

11.1.5. Use swaRef in WSDL.


W S-I Attachment Profile 1.0 defines mechanism to reference MIME attachment parts using swaRef. In this mechanism the content of XML element of type wsi:swaRef is sent as MIME attachment and the element inside SOAP Body holds the reference to this attachment in the CID URI scheme as defined by RFC 2111. JAXB 2.0 defines mapping of wsi:swaRef schema type to javax.activation.DataHandler. An application w ill construct the DataHandler w ith the data and the appropriate MIME type and JAX-W S w ill coordinate w ith JAXB and SAAJ to send it as attachment MIME part. An XML element of type wsi:swaRef is mapped to a DataHandler and is sent as attachment over the w ire. For example:

<element name="claimForm" type="wsi:swaRef" xmlns:wsi="http://ws-i.org/profiles/basic/1.1/xsd"/>

w ill be sent over the w ire as :

Content-Type: Multipart/Related; start-info="text/xml"; type="application/xop+xml"; boundary="------=_Part_5_32550604.1118953563502" Content-Length: 1193 SOAPAction: "" ------=_Part_5_32550604.1118953563502 Content-Type: application/xop+xml; type="text/xml"; charset=utf-8 <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <claimForm xmlns="http://example.org/mtom/data">cid:b0a597fd-5ef7-4f0c-9d85-6666239f1d25@example.jaxws.sun.com</claimForm> </soapenv:Body> </soapenv:Envelope>
converted by Web2PDFConvert.com

------=_Part_5_32550604.1118953563502 Content-Type: application/xml Content-ID: <b0a597fd-5ef7-4f0c-9d85-6666239f1d25@example.jaxws.sun.com> <?xml version="1.0" encoding="UTF-8"?> [ATTACHMENT CONTENT] ------=_Part_5_32550604.1118953563502

11.1.6. Use MIME binding in WSDL


blah-blah
Prev 10.4. Use Dispatch API to create a dynamic web service client. Up Home Next 11.2. Use MTOM on the client.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

11.2. Use MTOM on the client. Chapter 11. Use MTOM and MIME in a SOAP web service.

Next

11.2. Use MTOM on the client.


11.2.1. Use MTOMFeature with getPort() methods.
If you w ant to use MTOM, you should encode your binary data as xs:base64Binary content. Then enable MTOM on the client side by passing javax.xml.ws.MTOMFeature to the proxy constructor. For each port in the service, the generated client side service class contains the follow ing methods, tw o for each port defined by the W SDL service and w hose binding is supported by the JAX-W S implementation:

get<PortName>()
One required method that takes no parameters and returns a proxy that implements the mapped service endpoint interface. The method generated delegates to the Service.getPort(...) method passing it the port name. The value of the port name MUST be equal to the value specified in the mandatory WebEndpoint annotation on the method itself.

get<PortName>(WebServiceFeature... features)
One required method that takes a variable-length array of javax.xml.ws.WebServiceFeature and returns a proxy that implements the mapped service endpoint interface. The method generated delegates to the Service.getPort(QName portName, Class<T> SEI, WebServiceFeature... features) method passing it the port name, the SEI and the features. The value of the port name MUST be equal to the value specified in the mandatory WebEndpoint annotation on the method itself. Example of generated w eb service client:

@WebEndpoint(name = "CatalogPort") public Catalog getCatalogPort() { return super.getPort(new QName("http://example.com", "CatalogPort"), Catalog.class); } @WebEndpoint(name = "CatalogPort") public Catalog getCatalogPort(WebServiceFeature... features) { return super.getPort(new QName("http://example.com", "CatalogPort"), Catalog.class, features); }
A WebServiceFeature is a standard manner of enabling and disabling support for a variety of useful mechanisms at runtime. Some features come built in w ith JAX-W S, and vendors can provide additional features. You can also w rite your ow n. The class javax.xml.ws.soap.MTOMFeature extends WebServiceFeature. The generated client interfaces make it easy to invoke your service operations using a built-in or custom feature. To use MTOM on the client, simply retrieve the port using the factory that accepts a variable-length argument of WebServiceFeature objects, passing in an instance of the MTOMFeature. Here's how you can enable MTOM using the getCatalogPort method:

Catalog catalogPort = service.getCatalogPort(new MTOMFeature());


The implementation is handled for you by the runtime. The MTOMFeature constructor also accepts an optional integer argument indicating the threshold, or the number of bytes that the binary data should be before being sent as an attachment. The default value for the threshold is 0.

11.2.2. Use MTOM in the deployment descriptors.


blah-blah

11.2.3. Sending any additional attachments using MessageContext properties.


javax.xml.ws.handler.MessageContext

MessageContext is the super interface for all JAX-W S message contexts. It extends Map<String,Object> w ith additional methods and constants to manage a set of properties that enable handlers in a handler chain to share processing related state. For example, a handler may use the put method to insert a property in the message context that one or more other handlers in the handler chain may subsequently obtain via the get method.
Properties are scoped as either APPLICATION or HANDLER. All properties are available to all handlers for an instance of an MEP on a particular endpoint. E.g., if a logical handler puts a property in the message context, that property w ill also be available to any protocol handlers in the chain during the execution of an MEP instance. APPLICATION scoped properties are also made available to client applications and service endpoint implementations. The default scope for a property is HANDLER. Some standard message context properties:

javax.xml.ws.binding.attachments.inbound Type - Map<String,DataHandler>


A map of attachments to an inbound message. The key is a unique identifier for the attachment. The value is a DataHandler for the attachment data. Bindings describe how to carry attachments w ith messages.

javax.xml.ws.binding.attachments.outbound Type - Map<String,DataHandler>


A map of attachments to an outbound message. The key is a unique identifier for the attachment. The value is a DataHandler for the attachment data. Bindings describe how to carry attachments w ith messages. Mime attachments specified by the javax.xml.ws.binding.attachments.inbound and javax.xml.ws.binding.attachments.outbound properties defined in the MessageContext ( MessageContext.OUTBOUND_MESSAGE_ATTACHMENTS, MessageContext.INBOUND_MESSAGE_ATTACHMENTS)can be modified in logical handlers. A SOAP message w ith the attachments specified using the properties is generated before invoking the first SOAPHandler. Any changes to the tw o properites in consideration above in the MessageContext after invoking the first SOAPHandler are ignored. The SOAPHandler how ever may change the properties in the MessageContext. Use of javax.xml.ws.binding.attachments.outbound property in Dispatch: W hen using Dispatch in SOAP / HTTP binding in payload mode, attachments specified using the javax.xml.ws.binding.attachments.outbound property w ill be included as mime attachments in the message.

converted by Web2PDFConvert.com

W hen using Dispatch in SOAP / HTTP binding in message mode, the javax.xml.ws.binding.attachments.outbound property w ill be ignored as the message type already provides a w ay to specify attachments. For example:

// Create Dispatch for the payload Dispatch<String> dispatch = svc.createDispatch(portName, String.class, Service.Mode.PAYLOAD); // Get the request context Map<String, Object> requestContext = dispatch.getRequestContext(); // Get the attachments (non-payload) that should also be sent. Map<String, DataHandler> attachmentMap = new HashMap(); attachmentMap.put("myCID", myDataHandler); // Attach the attachments to the request context requestContext.put("javax.xml.ws.binding.attachments.outbound", attachmentMap);

Prev Chapter 11. Use MTOM and MIME in a SOAP web service.

Up Home

Next Chapter 12. Use WS-Addressing with a SOAP web service

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 12. Use WS-Addressing with a SOAP web service Part I. Exam Objectives

Next

Chapter 12. Use WS-Addressing with a SOAP web service


In a moderately complex system, a receiver of a message must know information about the sender. W ith an asynchronous request-response implementation model, the receiver must know at least the senders address to send back responses that are disconnected from the request channel that w as previously used by the Web services client to issue the request. The purpose of the W S-Addressing specification is to provide an interoperable w ay of communicating betw een senders and receivers by providing a transport-neutral mechanism to address Web services and messages. The W S-Addressing specification defines XML elements to identify the w eb services endpoints and to secure end-to-end endpoint identification in messages. This specification enables messaging systems to support message transmission through netw orks that include processing nodes, such as endpoint managers, firew alls, and gatew ays. W S-Addressing is a World W ide Web Consortium (W 3C) specification that aid interoperability betw een w eb services by defining a standard w ay to address w eb services and to provide addressing information in messages. The W S-Addressing specification introduces tw o primary concepts: Endpoint references Endpoint references provide a standard mechanism to encapsulate information about specific endpoints. Endpoint references can be propagated to other parties and then used to target the Web service endpoint that they represent. Message addressing properties Message addressing properties (MAPs) are a set of w ell-defined W S-Addressing properties that can be represented as elements in SOAP headers and provide a standard w ay of conveying information, such as the endpoint to w hich to a direct message replies, or information about the relationship that the message has w ith other messages. For JAX-W S applications, you can enable W S-Addressing support in several w ays, such as configuring policy sets or using annotations in code. You can now use JAX-W S 2.1 annotations and feature classes to do the follow ing tasks: Enable W S-Addressing from either the server or the client. Have more control over the behavior of W S-Addressing w hen using policy sets. Specify w hether W S-Addressing is enabled and w hether to use synchronous, asynchronous, or both messaging patterns. Specify actions to be associated w ith a Web service operation or fault response. For w eb service clients, W S-Addressing support is disabled by default. For w eb service providers, W S-Addressing support is enabled by default. Therefore, you do not have to enable this support. How ever, you can use the enabling mechanisms to modify other W S-Addressing behavior for the service, such as w hether W S-Addressing information is required and w hat is included in the generated W SDL document. The follow ing additional features are related to the JAX-W S enhancements: Java representations of W S-Addressing endpoint references are available. You can create Java endpoint reference instances for the application endpoint, or other endpoints in the same application, at run time. You do not have to specify the URI of the endpoint reference. You can create Java endpoint reference instances for endpoints in other applications by specifying the URI of the endpoint reference. On services, you can use annotations to specify w hether W S-Addressing support is enabled and w hether it is required. On clients, you can use features to specify w hether W S-Addressing support is enabled and w hether it is required. You can configure client proxy or dispatch objects by using endpoint references. Java support for endpoint references that represent w eb services Resource (W S-Resource) instances is available. You can associate reference parameters w ith an endpoint reference at the time of its creation to correlate it w ith a particular resource instance. In targeted w eb services, you can extract the reference parameters of an incoming message so that the w eb service can route the message to the appropriate W SResource instance.

12.1. Use Addressing on the service


12.1.1. Use @Addressing annotation with a web service
javax.xml.ws.soap.Addressing package javax.xml.ws.soap; @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented @WebServiceFeatureAnnotation(id=AddressingFeature.ID,bean=AddressingFeature.class) public @interface Addressing { /** * Specifies if this feature is enabled or disabled. If enabled, it means * the endpoint supports WS-Addressing but does not require its use. * Corresponding Addressing Assertion must be generated in the generated WSDL. */ boolean enabled() default true; /** * If addressing is enabled, this property determines whether the endpoint * requires WS-Addressing. If required is true, the endpoint requires * WS-Addressing and WS-Addressing headers MUST * be present on incoming messages. A corresponding Addressing Assertion * must be generated in the WSDL. */ boolean required() default false;

converted by Web2PDFConvert.com

/** * If addressing is enabled, this property determines whether endpoint * requires the use of anonymous responses, or non-anonymous responses, * or all. * * Responses.ALL supports all response types and this is the default value. * * Responses.ANONYMOUS requires the use of only anonymous * responses. It will result into wsam:AnonymousResponses nested assertion * as specified in AnonymousResponses Assertion in the generated WSDL. * * Responses.NON_ANONYMOUS requires the use of only non-anonymous * responses. It will result into wsam:NonAnonymousResponses nested assertion * as specified in NonAnonymousResponses Assertion in the generated WSDL. * * @since JAX-WS 2.2 */ Responses responses() default Responses.ALL; }

This annotation represents the use of W S-Addressing w ith either the SOAP 1.1/HTTP or SOAP 1.2/HTTP binding. Using this annotation w ith any other binding is undefined. This annotation MUST only be used in conjunction w ith the WebService, WebServiceProvider, and WebServiceRef annotations. W hen used w ith a javax.jws.WebService annotation, this annotation MUST only be used on the service endpoint implementation class. W hen used w ith a WebServiceRef annotation, this annotation MUST only be used w hen a proxy instance is created. The injected SEI proxy, and endpoint MUST honor the values of the @Addressing annotation. The required property can be used to specify if W S-Addressing headers MUST be present on incoming messages. By default the required property is false. This annotation's behaviour is defined by the corresponding feature AddressingFeature. The Addressing specification is w rapped into the JAX-W S 2.1 specification, so any vendor implementing JAX-W S 2.1 w ill make the Addressing feature available. In your Java w eb service class, use the javax.xml.ws.soap.Addressing annotation along w ith the javax.xml.ws.Action annotation:

import javax.xml.ws.Action; import javax.xml.ws.soap.Addressing; /** * @author Mikalai Zaikin */ @WebService() @Addressing(enabled=true, required=true) public class CalculatorWS {
This enables Addressing generally in your service; you must then apply the @Action annotation to your operations, like this:

/** * Web service operation */ @WebMethod(operationName = "add") @Action( input="http://addnumbers.org/input", output="http://addnumbers.org/output") public int add(@WebParam(name = "i") int i, @WebParam(name = "j") int j) { return i + j; }
Let's unpack the code a little bit to see how this w orks. Adding addressing to your simple Calculator service as you did earlier makes the follow ing changes to the resulting W SDL:

<portType name="CalculatorWS"> <operation name="add"> <input wsaw:Action="http://addnumbers.org/input" message="tns:add"/> <output wsaw:Action="http://addnumbers.org/output" message="tns:addResponse"/> </operation> </portType> ... <binding name="CalculatorWSPortBinding" type="tns:CalculatorWS"> <wsaw:UsingAddressing/> ... </binding>

First, the annotation's attributes map clearly to the input and output of the operation they modify. The values specified in the Java file are added to the addressing Action attribute. Then, in the binding, the W SDL now indicates that it is set up for W S-Addressing so that clients are free to use Addressing if they w ould like to, via the <wsaw:UsingAddressing/> element. This element also has a required attribute that indicates if you w ant the service to force clients to use addressing. By default, it is set to false. But you could just w rite <wsaw:UsingAddressing required="true"/> to force clients to use Addressing, if you had started from W SDL. To generate that from

converted by Web2PDFConvert.com

Java, use the follow ing code:

@Addressing(required=true)
To make sure that your endpoint and its client are portable, the endpoint must use the @Action annotation to indicate their W S-Addressing actions, and it should use the @FaultAction annotation for creating W S-Addressing-compliant SOAP faults.

12.1.2. Use wsam:Addressing policy in WSDL


If the endpoint enables Addressing, that can be indicated in the generated W SDL as per the Addressing 1.0 - Metadata. Endpoint's use of addressing, if any, MUST be indicated in the wsdl:binding or wsdl:port sections of the W SDL 1.1 as per W S-Addressing 1.0 - Metadata. Example 1: Possible Policy assertion for @Addressing in the generated W SDL:

@WebService() @Addressing public class CalculatorWS {

<wsam:Addressing wsp:Optional="true"> <wsp:Policy/> </wsam:Addressing>

Example 2: Possible Policy assertion for @Addressing(required=true) in the generated W SDL:

@WebService() @Addressing(required=true) public class CalculatorWS {

<wsam:Addressing> <wsp:Policy/> </wsam:Addressing>

Example 3: Possible Policy assertion for @Addressing(responses=Responses.NON_ANONYMOUS) in the generated W SDL:

@WebService() @Addressing(responses=Responses.NON_ANONYMOUS) public class CalculatorWS {

<wsam:Addressing wsp:Optional="true"> <wsp:Policy> <wsam:NonAnonymousResponses/> </wsp:Policy> </wsam:Addressing>

12.1.3. Use Addressing in the deployment descriptors


Deployment descriptors are standard text files, formatted using XML and packaged in a w eb services application. You can optionally use the webservices.xml deployment descriptor to augment or override application metadata specified in annotations w ithin Java API for XML-Based Web Services (JAX-W S) Web services. For JAX-W S w eb services, the use of the webservices.xml deployment descriptor is optional because you can use annotations to specify all of the information that is contained w ithin the deployment descriptor file. You can use the deployment descriptor file to augment or override existing JAX-W S annotations. Any information that you define in the webservices.xml deployment descriptor overrides any corresponding information that is specified by annotations. The deployment descriptor must be named "META-INF/webservices.xml" in the w eb services' jar file.

http://java.sun.com/xml/ns/javaee/javaee_web_services_1_3.xsd XSD:

<xsd:element name="addressing" type="javaee:addressingType" minOccurs="0" maxOccurs="1"> <xsd:annotation> <xsd:documentation> This specifies the WS-Addressing requirements for a JAX-WS web service. It corresponds to javax.xml.ws.soap.Addressing annotation or its feature javax.xml.ws.soap.AddressingFeature. See the addressingType for more information. </xsd:documentation>
converted by Web2PDFConvert.com

</xsd:annotation> </xsd:element>

12.1.4. Use AddressingFeature with javax.xml.ws.Endpoint API.


JAX-W S 2.1 introduces the notion of features. A feature is associated w ith a particular functionality or behavior. Some features may only have meaning w hen used w ith certain bindings w hile other features may be generally useful. These features can be used w hile creating service and proxy instances. JAX-W S 2.1 introduces three standard features for creating proxy instances, AddressingFeature, MTOMFeature and RespectBindingFeature as w ell as the base WebServiceFeature class. The AddressingFeature is used to control the use of W S-Addressing by JAX-W S. This feature MUST be supported w ith the SOAP 1.1/HTTP or SOAP 1.2/HTTP bindings. Using this feature w ith any other binding is undened. This feature corresponds to the @Addressing annotation. Enabling this feature on the server w ill result in the runtime being capable of consuming and responding to W S-Addressing headers. Enabling this feature on the client w ill cause the JAX-W S runtime to include W S-Addressing headers in SOAP messages as specied by W S-Addressing. Disabling this feature w ill prevent a JAX-W S runtime from processing or adding W S-Addressing headers from/to SOAP messages even if the associated W SDL specifies otherw ise. This may be necessary if a client or endpoint needs to implement Addressing themselves. For example, a client that desires to use non-anonymous ReplyTo can do so by disabling the AddressingFeature and by using Dispatch<Source> w ith Message mode. The AddressingFeature's required property can be congured to control w hether all incoming messages MUST contain Addressing headers. The AddressingFeature's responses property can be congured to control w hether the endpoint requires the use of anonymous, non-anonymous and all responses. This feature is automatically enabled if the W SDL indicates the use of addressing as per the W S-Addressing 1.0 - Metadata. Developers may choose to prevent this from happening by explicitly disabling the AddressingFeature. To w rite a portable endpoint and its corresponding client w ith this version of JAX-W S, an endpoint MUST explicitly specify w hat W S-Addressing Actions are to be used via the Action and FaultAction annotations. The client MUST explicitly enable addresssing via this AddressingFeature, and for each invocation, the client MUST explicitly set the BindingProvider.SOAPACTION_URI_PROPERTY. After the W 3C W G on W S-Addressing has specified how the use of W S-Addressing is specified in the W SDL, and w hat the default value must be for Action headers, a future version of JAX-W S w ill remove these requirements. The follow ing describes the effects of this feature w ith respect to be enabled or disabled: ENABLED In this Mode, W S-Addressing w ill be enabled. At runtime, W S-Addressing headers MUST be consumed by the receiver and produced by the sender even if the W SDL declares otherw ise. The mustUnderstand="0" attribute MUST be used on the W S-Addressing headers. DISABLED In this Mode, W S-Addressing w ill be disabled even if an associated W SDL specifies otherw ise. At runtime, W S-Addressing headers MUST NOT be used. W S-Addressing may be explicitly disabled to prevent a JAX-W S implementation from consuming and producing W S-Addressing headers. If an application has implemented W S-Addressing itself, it MUST explicitly disable this feature. Not doing so may break compatibility w ith future versions of JAX-W S. The required property can be used to specify if W S-Addressing headers MUST be present on incoming messages. This property only has meaning w hen used on the endpoint and has no affect w hen used on the client. By default the required property is false. Constructor summary:

AddressingFeature() AddressingFeature(boolean enabled) AddressingFeature(boolean enabled, boolean required)


The Endpoint class can be used to create and publish w eb service endpoints. An endpoint consists of an object that acts as the w eb service implementation (called here implementor) plus some configuration information, e.g. a Binding. Implementor and binding are set w hen the endpoint is created and cannot be modified later. Their values can be retrieved using the getImplementor and getBinding methods respectively. Other configuration information may be set at any time after the creation of an Endpoint but before its publication. Endpoints can be created using the follow ing static methods on Endpoint:

create(Object implementor)
Creates and returns an Endpoint for the specified implementor. If the implementor specifies a binding using the javax.xml.ws.BindingType annotation it MUST be used else a default binding of SOAP 1.1 / HTTP binding MUST be used.

create(Object implementor, WebServiceFeature ... features)


Same as the above create() method. The created Endpoint is congured w ith the w eb service features. These features override the corresponding features that are specied in W SDL, if present.

create(String bindingID, Object implementor)


Creates and returns an Endpoint for the specified binding and implementor. If the bindingID is null and no binding information is specified via the javax.xml.ws.BindingType annotation then a default SOAP 1.1 / HTTP binding MUST be used.

create(String bindingID, Object implementor, WebServiceFeature ... features)


Same as the above create() method. The created Endpoint is congured w ith the w eb service features. These features override the corresponding features that are specied in W SDL, if present.

publish(String address, Object implementor)


Creates and publishes an Endpoint for the given implementor. The binding is chosen by default based on the URL scheme of the provided address (w hich must be a URL). If a suitable binding if found, the endpoint is created then published as if the Endpoint.publish(String address) method had been called. The created Endpoint is then returned as the value of the method.

publish(String address, Object implementor, WebServiceFeature ... features)

converted by Web2PDFConvert.com

Same as the above publish() method. The created Endpoint is congured w ith the w eb service features. These features override the corresponding features that are specied in W SDL, if present. These methods MUST delegate the creation of Endpoint to the javax.xml.ws.spi.Provider SPI class by calling the createEndpoint and createAndPublishEndpoint methods respectively. An implementor object MUST be either an instance of a class annotated w ith the @WebService annotation or an instance of a class annotated w ith the @WebServiceProvider annotation and implementing the Provider interface. The publish(String,Object) method is provided as a shortcut for the common operation of creating and publishing an Endpoint. The follow ing code provides an example of its use:

// assume Test is an endpoint implementation class annotated with @WebService Test test = new Test(); Endpoint e = Endpoint.publish("http://localhost:8080/test", test);

12.1.5. Use @Action and @FaultAction on the service methods.


javax.xml.ws.Action
The @Action annotation is applied to the methods of a SEI. It is used to specify the input, output, fault W S-Addressing Action values associated w ith the annotated method. For such a method, the mapped operation in the generated W SDL's wsam:Action attribute on the W SDL input, output and fault messages of the W SDL operation is based upon w hich attributes of the @Action annotation have been specified.

public @interface Action { /** * Explicit value of the WS-Addressing Action message addressing property for the input * message of the operation. */ String input() default ""; /** * Explicit value of the WS-Addressing Action message addressing property for the output * message of the operation. */ String output() default ""; /** * Explicit value of the WS-Addressing Action message addressing property for the fault * message(s) of the operation. Each exception that is mapped to a fault and requires an explicit WS-Addressing * Action message addressing property, needs to be specified as a value in this property * using @FaultAction annotation. */ FaultAction[] fault() default { }; } javax.xml.ws.FaultAction
The @FaultAction annotation is used w ithin the @Action annotation to specify the W S-Addressing Action of a service specific exception. The wsam:Action attribute value in the fault message in the generated W SDL operation mapped for an exception class is equal to the corresponding value in the FaultAction.

public @interface FaultAction { /** * Name of the exception class */ Class className(); /** * Value of WS-Addressing Action message addressing property for the exception */ String value() default ""; }
JAX-W S 2.1 defines javax.xml.ws.Action and javax.xml.ws.FaultAction annotations to explicitly associate an Action w ith input, output, and fault messages of the mapped W SDL operation. For example:

@Action( input = "http://example.com/input3", output = "http://example.com/output3", fault = { @FaultAction(className = AddNumbersException.class, value = "http://example.com/fault3") }) public int addNumbers3(int number1, int number2) throws AddNumbersException { ... }
The generated W SDL fragment looks like:

converted by Web2PDFConvert.com

<operation name="addNumbers3"> <input wsaw:Action="http://example.com/input3" message="tns:addNumbers3"/> <output wsaw:Action="http://example.com/output3" message="tns:addNumbers3Response"/> <fault message="tns:AddNumbersException" name="AddNumbersException" wsaw:Action="http://example.com/fault3"/> </operation>

12.1.6. Use WebServiceContext.getEndpointReference()


An endpoint implementation can retrieve an javax.xml.ws.EndpointReference for the endpoint using getEndpointReference(List<Element> referenceParameters), and getEndpointReference(Class<T> clazz, List<Element> referenceParameters) methods. These methods have the same semantics as the Endpoint.getEndpointReference() methods. The follow ing methods can be used on a published Endpoint to retrieve an javax.xml.ws.EndpointReference for the Endpoint instance:

getEndpointReference(List<Element> referenceParameters)
Creates and returns javax.xml.ws.EndpointReference for a published Endpoint. If the binding is SOAP 1.1/HTTP or SOAP 1.2/HTTP, then a javax.xml.ws.wsaddressing.W3CEndpointReference MUST be returned. A returned W3CEndpointReference MUST also contain the specified referenceParameters.

getEndpointReference(Class<T> clazz, List<Element> referenceParameters)


Creates and returns and javax.xml.ws.EndpointReference of type clazz for a published Endpoint instance. If clazz is of type javax.xml.ws.wsaddressing.W3CEndpointReference, then the returned W3CEndpointReference MUST contain the specied referenceParameters.

javax.xml.ws.W3CEndpointReference
The W3CEndpointReference class is a concrete implementation of the javax.xml.ws.EndpointReference class and is used to reference endpoints that are compliant w ith the W 3C Web Services Addressing 1.0 - Core recommendation. Applications may use this class to pass EndpointReference instancess as method parameters or return types. JAXB 2.1 w ill bind the W3CEndpointReference class to the W 3C EndpointReference XML Schema in the W SDL.
Prev 11.2. Use MTOM on the client. Up Home Next 12.2. Use Addressing on the client.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

Prev

Chapter 12. Use WS-Addressing with a SOAP web service Part I. Exam Objectives

Next

Chapter 12. Use WS-Addressing with a SOAP web service


In a moderately complex system, a receiver of a message must know information about the sender. W ith an asynchronous request-response implementation model, the receiver must know at least the senders address to send back responses that are disconnected from the request channel that w as previously used by the Web services client to issue the request. The purpose of the W S-Addressing specification is to provide an interoperable w ay of communicating betw een senders and receivers by providing a transport-neutral mechanism to address Web services and messages. The W S-Addressing specification defines XML elements to identify the w eb services endpoints and to secure end-to-end endpoint identification in messages. This specification enables messaging systems to support message transmission through netw orks that include processing nodes, such as endpoint managers, firew alls, and gatew ays. W S-Addressing is a World W ide Web Consortium (W 3C) specification that aid interoperability betw een w eb services by defining a standard w ay to address w eb services and to provide addressing information in messages. The W S-Addressing specification introduces tw o primary concepts: Endpoint references Endpoint references provide a standard mechanism to encapsulate information about specific endpoints. Endpoint references can be propagated to other parties and then used to target the Web service endpoint that they represent. Message addressing properties Message addressing properties (MAPs) are a set of w ell-defined W S-Addressing properties that can be represented as elements in SOAP headers and provide a standard w ay of conveying information, such as the endpoint to w hich to a direct message replies, or information about the relationship that the message has w ith other messages. For JAX-W S applications, you can enable W S-Addressing support in several w ays, such as configuring policy sets or using annotations in code. You can now use JAX-W S 2.1 annotations and feature classes to do the follow ing tasks: Enable W S-Addressing from either the server or the client. Have more control over the behavior of W S-Addressing w hen using policy sets. Specify w hether W S-Addressing is enabled and w hether to use synchronous, asynchronous, or both messaging patterns. Specify actions to be associated w ith a Web service operation or fault response. For w eb service clients, W S-Addressing support is disabled by default. For w eb service providers, W S-Addressing support is enabled by default. Therefore, you do not have to enable this support. How ever, you can use the enabling mechanisms to modify other W S-Addressing behavior for the service, such as w hether W S-Addressing information is required and w hat is included in the generated W SDL document. The follow ing additional features are related to the JAX-W S enhancements: Java representations of W S-Addressing endpoint references are available. You can create Java endpoint reference instances for the application endpoint, or other endpoints in the same application, at run time. You do not have to specify the URI of the endpoint reference. You can create Java endpoint reference instances for endpoints in other applications by specifying the URI of the endpoint reference. On services, you can use annotations to specify w hether W S-Addressing support is enabled and w hether it is required. On clients, you can use features to specify w hether W S-Addressing support is enabled and w hether it is required. You can configure client proxy or dispatch objects by using endpoint references. Java support for endpoint references that represent w eb services Resource (W S-Resource) instances is available. You can associate reference parameters w ith an endpoint reference at the time of its creation to correlate it w ith a particular resource instance. In targeted w eb services, you can extract the reference parameters of an incoming message so that the w eb service can route the message to the appropriate W SResource instance.

12.1. Use Addressing on the service


12.1.1. Use @Addressing annotation with a web service
javax.xml.ws.soap.Addressing package javax.xml.ws.soap; @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented @WebServiceFeatureAnnotation(id=AddressingFeature.ID,bean=AddressingFeature.class) public @interface Addressing { /** * Specifies if this feature is enabled or disabled. If enabled, it means * the endpoint supports WS-Addressing but does not require its use. * Corresponding Addressing Assertion must be generated in the generated WSDL. */ boolean enabled() default true; /** * If addressing is enabled, this property determines whether the endpoint * requires WS-Addressing. If required is true, the endpoint requires * WS-Addressing and WS-Addressing headers MUST * be present on incoming messages. A corresponding Addressing Assertion * must be generated in the WSDL. */ boolean required() default false;

converted by Web2PDFConvert.com

/** * If addressing is enabled, this property determines whether endpoint * requires the use of anonymous responses, or non-anonymous responses, * or all. * * Responses.ALL supports all response types and this is the default value. * * Responses.ANONYMOUS requires the use of only anonymous * responses. It will result into wsam:AnonymousResponses nested assertion * as specified in AnonymousResponses Assertion in the generated WSDL. * * Responses.NON_ANONYMOUS requires the use of only non-anonymous * responses. It will result into wsam:NonAnonymousResponses nested assertion * as specified in NonAnonymousResponses Assertion in the generated WSDL. * * @since JAX-WS 2.2 */ Responses responses() default Responses.ALL; }

This annotation represents the use of W S-Addressing w ith either the SOAP 1.1/HTTP or SOAP 1.2/HTTP binding. Using this annotation w ith any other binding is undefined. This annotation MUST only be used in conjunction w ith the WebService, WebServiceProvider, and WebServiceRef annotations. W hen used w ith a javax.jws.WebService annotation, this annotation MUST only be used on the service endpoint implementation class. W hen used w ith a WebServiceRef annotation, this annotation MUST only be used w hen a proxy instance is created. The injected SEI proxy, and endpoint MUST honor the values of the @Addressing annotation. The required property can be used to specify if W S-Addressing headers MUST be present on incoming messages. By default the required property is false. This annotation's behaviour is defined by the corresponding feature AddressingFeature. The Addressing specification is w rapped into the JAX-W S 2.1 specification, so any vendor implementing JAX-W S 2.1 w ill make the Addressing feature available. In your Java w eb service class, use the javax.xml.ws.soap.Addressing annotation along w ith the javax.xml.ws.Action annotation:

import javax.xml.ws.Action; import javax.xml.ws.soap.Addressing; /** * @author Mikalai Zaikin */ @WebService() @Addressing(enabled=true, required=true) public class CalculatorWS {
This enables Addressing generally in your service; you must then apply the @Action annotation to your operations, like this:

/** * Web service operation */ @WebMethod(operationName = "add") @Action( input="http://addnumbers.org/input", output="http://addnumbers.org/output") public int add(@WebParam(name = "i") int i, @WebParam(name = "j") int j) { return i + j; }
Let's unpack the code a little bit to see how this w orks. Adding addressing to your simple Calculator service as you did earlier makes the follow ing changes to the resulting W SDL:

<portType name="CalculatorWS"> <operation name="add"> <input wsaw:Action="http://addnumbers.org/input" message="tns:add"/> <output wsaw:Action="http://addnumbers.org/output" message="tns:addResponse"/> </operation> </portType> ... <binding name="CalculatorWSPortBinding" type="tns:CalculatorWS"> <wsaw:UsingAddressing/> ... </binding>

First, the annotation's attributes map clearly to the input and output of the operation they modify. The values specified in the Java file are added to the addressing Action attribute. Then, in the binding, the W SDL now indicates that it is set up for W S-Addressing so that clients are free to use Addressing if they w ould like to, via the <wsaw:UsingAddressing/> element. This element also has a required attribute that indicates if you w ant the service to force clients to use addressing. By default, it is set to false. But you could just w rite <wsaw:UsingAddressing required="true"/> to force clients to use Addressing, if you had started from W SDL. To generate that from

converted by Web2PDFConvert.com

Java, use the follow ing code:

@Addressing(required=true)
To make sure that your endpoint and its client are portable, the endpoint must use the @Action annotation to indicate their W S-Addressing actions, and it should use the @FaultAction annotation for creating W S-Addressing-compliant SOAP faults.

12.1.2. Use wsam:Addressing policy in WSDL


If the endpoint enables Addressing, that can be indicated in the generated W SDL as per the Addressing 1.0 - Metadata. Endpoint's use of addressing, if any, MUST be indicated in the wsdl:binding or wsdl:port sections of the W SDL 1.1 as per W S-Addressing 1.0 - Metadata. Example 1: Possible Policy assertion for @Addressing in the generated W SDL:

@WebService() @Addressing public class CalculatorWS {

<wsam:Addressing wsp:Optional="true"> <wsp:Policy/> </wsam:Addressing>

Example 2: Possible Policy assertion for @Addressing(required=true) in the generated W SDL:

@WebService() @Addressing(required=true) public class CalculatorWS {

<wsam:Addressing> <wsp:Policy/> </wsam:Addressing>

Example 3: Possible Policy assertion for @Addressing(responses=Responses.NON_ANONYMOUS) in the generated W SDL:

@WebService() @Addressing(responses=Responses.NON_ANONYMOUS) public class CalculatorWS {

<wsam:Addressing wsp:Optional="true"> <wsp:Policy> <wsam:NonAnonymousResponses/> </wsp:Policy> </wsam:Addressing>

12.1.3. Use Addressing in the deployment descriptors


Deployment descriptors are standard text files, formatted using XML and packaged in a w eb services application. You can optionally use the webservices.xml deployment descriptor to augment or override application metadata specified in annotations w ithin Java API for XML-Based Web Services (JAX-W S) Web services. For JAX-W S w eb services, the use of the webservices.xml deployment descriptor is optional because you can use annotations to specify all of the information that is contained w ithin the deployment descriptor file. You can use the deployment descriptor file to augment or override existing JAX-W S annotations. Any information that you define in the webservices.xml deployment descriptor overrides any corresponding information that is specified by annotations. The deployment descriptor must be named "META-INF/webservices.xml" in the w eb services' jar file.

http://java.sun.com/xml/ns/javaee/javaee_web_services_1_3.xsd XSD:

<xsd:element name="addressing" type="javaee:addressingType" minOccurs="0" maxOccurs="1"> <xsd:annotation> <xsd:documentation> This specifies the WS-Addressing requirements for a JAX-WS web service. It corresponds to javax.xml.ws.soap.Addressing annotation or its feature javax.xml.ws.soap.AddressingFeature. See the addressingType for more information. </xsd:documentation>
converted by Web2PDFConvert.com

</xsd:annotation> </xsd:element>

12.1.4. Use AddressingFeature with javax.xml.ws.Endpoint API.


JAX-W S 2.1 introduces the notion of features. A feature is associated w ith a particular functionality or behavior. Some features may only have meaning w hen used w ith certain bindings w hile other features may be generally useful. These features can be used w hile creating service and proxy instances. JAX-W S 2.1 introduces three standard features for creating proxy instances, AddressingFeature, MTOMFeature and RespectBindingFeature as w ell as the base WebServiceFeature class. The AddressingFeature is used to control the use of W S-Addressing by JAX-W S. This feature MUST be supported w ith the SOAP 1.1/HTTP or SOAP 1.2/HTTP bindings. Using this feature w ith any other binding is undened. This feature corresponds to the @Addressing annotation. Enabling this feature on the server w ill result in the runtime being capable of consuming and responding to W S-Addressing headers. Enabling this feature on the client w ill cause the JAX-W S runtime to include W S-Addressing headers in SOAP messages as specied by W S-Addressing. Disabling this feature w ill prevent a JAX-W S runtime from processing or adding W S-Addressing headers from/to SOAP messages even if the associated W SDL specifies otherw ise. This may be necessary if a client or endpoint needs to implement Addressing themselves. For example, a client that desires to use non-anonymous ReplyTo can do so by disabling the AddressingFeature and by using Dispatch<Source> w ith Message mode. The AddressingFeature's required property can be congured to control w hether all incoming messages MUST contain Addressing headers. The AddressingFeature's responses property can be congured to control w hether the endpoint requires the use of anonymous, non-anonymous and all responses. This feature is automatically enabled if the W SDL indicates the use of addressing as per the W S-Addressing 1.0 - Metadata. Developers may choose to prevent this from happening by explicitly disabling the AddressingFeature. To w rite a portable endpoint and its corresponding client w ith this version of JAX-W S, an endpoint MUST explicitly specify w hat W S-Addressing Actions are to be used via the Action and FaultAction annotations. The client MUST explicitly enable addresssing via this AddressingFeature, and for each invocation, the client MUST explicitly set the BindingProvider.SOAPACTION_URI_PROPERTY. After the W 3C W G on W S-Addressing has specified how the use of W S-Addressing is specified in the W SDL, and w hat the default value must be for Action headers, a future version of JAX-W S w ill remove these requirements. The follow ing describes the effects of this feature w ith respect to be enabled or disabled: ENABLED In this Mode, W S-Addressing w ill be enabled. At runtime, W S-Addressing headers MUST be consumed by the receiver and produced by the sender even if the W SDL declares otherw ise. The mustUnderstand="0" attribute MUST be used on the W S-Addressing headers. DISABLED In this Mode, W S-Addressing w ill be disabled even if an associated W SDL specifies otherw ise. At runtime, W S-Addressing headers MUST NOT be used. W S-Addressing may be explicitly disabled to prevent a JAX-W S implementation from consuming and producing W S-Addressing headers. If an application has implemented W S-Addressing itself, it MUST explicitly disable this feature. Not doing so may break compatibility w ith future versions of JAX-W S. The required property can be used to specify if W S-Addressing headers MUST be present on incoming messages. This property only has meaning w hen used on the endpoint and has no affect w hen used on the client. By default the required property is false. Constructor summary:

AddressingFeature() AddressingFeature(boolean enabled) AddressingFeature(boolean enabled, boolean required)


The Endpoint class can be used to create and publish w eb service endpoints. An endpoint consists of an object that acts as the w eb service implementation (called here implementor) plus some configuration information, e.g. a Binding. Implementor and binding are set w hen the endpoint is created and cannot be modified later. Their values can be retrieved using the getImplementor and getBinding methods respectively. Other configuration information may be set at any time after the creation of an Endpoint but before its publication. Endpoints can be created using the follow ing static methods on Endpoint:

create(Object implementor)
Creates and returns an Endpoint for the specified implementor. If the implementor specifies a binding using the javax.xml.ws.BindingType annotation it MUST be used else a default binding of SOAP 1.1 / HTTP binding MUST be used.

create(Object implementor, WebServiceFeature ... features)


Same as the above create() method. The created Endpoint is congured w ith the w eb service features. These features override the corresponding features that are specied in W SDL, if present.

create(String bindingID, Object implementor)


Creates and returns an Endpoint for the specified binding and implementor. If the bindingID is null and no binding information is specified via the javax.xml.ws.BindingType annotation then a default SOAP 1.1 / HTTP binding MUST be used.

create(String bindingID, Object implementor, WebServiceFeature ... features)


Same as the above create() method. The created Endpoint is congured w ith the w eb service features. These features override the corresponding features that are specied in W SDL, if present.

publish(String address, Object implementor)


Creates and publishes an Endpoint for the given implementor. The binding is chosen by default based on the URL scheme of the provided address (w hich must be a URL). If a suitable binding if found, the endpoint is created then published as if the Endpoint.publish(String address) method had been called. The created Endpoint is then returned as the value of the method.

publish(String address, Object implementor, WebServiceFeature ... features)

converted by Web2PDFConvert.com

Same as the above publish() method. The created Endpoint is congured w ith the w eb service features. These features override the corresponding features that are specied in W SDL, if present. These methods MUST delegate the creation of Endpoint to the javax.xml.ws.spi.Provider SPI class by calling the createEndpoint and createAndPublishEndpoint methods respectively. An implementor object MUST be either an instance of a class annotated w ith the @WebService annotation or an instance of a class annotated w ith the @WebServiceProvider annotation and implementing the Provider interface. The publish(String,Object) method is provided as a shortcut for the common operation of creating and publishing an Endpoint. The follow ing code provides an example of its use:

// assume Test is an endpoint implementation class annotated with @WebService Test test = new Test(); Endpoint e = Endpoint.publish("http://localhost:8080/test", test);

12.1.5. Use @Action and @FaultAction on the service methods.


javax.xml.ws.Action
The @Action annotation is applied to the methods of a SEI. It is used to specify the input, output, fault W S-Addressing Action values associated w ith the annotated method. For such a method, the mapped operation in the generated W SDL's wsam:Action attribute on the W SDL input, output and fault messages of the W SDL operation is based upon w hich attributes of the @Action annotation have been specified.

public @interface Action { /** * Explicit value of the WS-Addressing Action message addressing property for the input * message of the operation. */ String input() default ""; /** * Explicit value of the WS-Addressing Action message addressing property for the output * message of the operation. */ String output() default ""; /** * Explicit value of the WS-Addressing Action message addressing property for the fault * message(s) of the operation. Each exception that is mapped to a fault and requires an explicit WS-Addressing * Action message addressing property, needs to be specified as a value in this property * using @FaultAction annotation. */ FaultAction[] fault() default { }; } javax.xml.ws.FaultAction
The @FaultAction annotation is used w ithin the @Action annotation to specify the W S-Addressing Action of a service specific exception. The wsam:Action attribute value in the fault message in the generated W SDL operation mapped for an exception class is equal to the corresponding value in the FaultAction.

public @interface FaultAction { /** * Name of the exception class */ Class className(); /** * Value of WS-Addressing Action message addressing property for the exception */ String value() default ""; }
JAX-W S 2.1 defines javax.xml.ws.Action and javax.xml.ws.FaultAction annotations to explicitly associate an Action w ith input, output, and fault messages of the mapped W SDL operation. For example:

@Action( input = "http://example.com/input3", output = "http://example.com/output3", fault = { @FaultAction(className = AddNumbersException.class, value = "http://example.com/fault3") }) public int addNumbers3(int number1, int number2) throws AddNumbersException { ... }
The generated W SDL fragment looks like:

converted by Web2PDFConvert.com

<operation name="addNumbers3"> <input wsaw:Action="http://example.com/input3" message="tns:addNumbers3"/> <output wsaw:Action="http://example.com/output3" message="tns:addNumbers3Response"/> <fault message="tns:AddNumbersException" name="AddNumbersException" wsaw:Action="http://example.com/fault3"/> </operation>

12.1.6. Use WebServiceContext.getEndpointReference()


An endpoint implementation can retrieve an javax.xml.ws.EndpointReference for the endpoint using getEndpointReference(List<Element> referenceParameters), and getEndpointReference(Class<T> clazz, List<Element> referenceParameters) methods. These methods have the same semantics as the Endpoint.getEndpointReference() methods. The follow ing methods can be used on a published Endpoint to retrieve an javax.xml.ws.EndpointReference for the Endpoint instance:

getEndpointReference(List<Element> referenceParameters)
Creates and returns javax.xml.ws.EndpointReference for a published Endpoint. If the binding is SOAP 1.1/HTTP or SOAP 1.2/HTTP, then a javax.xml.ws.wsaddressing.W3CEndpointReference MUST be returned. A returned W3CEndpointReference MUST also contain the specified referenceParameters.

getEndpointReference(Class<T> clazz, List<Element> referenceParameters)


Creates and returns and javax.xml.ws.EndpointReference of type clazz for a published Endpoint instance. If clazz is of type javax.xml.ws.wsaddressing.W3CEndpointReference, then the returned W3CEndpointReference MUST contain the specied referenceParameters.

javax.xml.ws.W3CEndpointReference
The W3CEndpointReference class is a concrete implementation of the javax.xml.ws.EndpointReference class and is used to reference endpoints that are compliant w ith the W 3C Web Services Addressing 1.0 - Core recommendation. Applications may use this class to pass EndpointReference instancess as method parameters or return types. JAXB 2.1 w ill bind the W3CEndpointReference class to the W 3C EndpointReference XML Schema in the W SDL.
Prev 11.2. Use MTOM on the client. Up Home Next 12.2. Use Addressing on the client.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

converted by Web2PDFConvert.com

12.2. Use Addressing on the client. Prev Chapter 12. Use WS-Addressing with a SOAP web service Next

12.2. Use Addressing on the client.

12.2.1. Use AddressingFeature with getPort() methods.


Create an instance of javax.xml.ws.AddressingFeature, using true as a constructor parameter. Then pass this feature instance to the port accessor method on the service stub you got from wsimport (or its equivalent). The code to do so looks like this:

new MyImplService().getMyImplPort( new javax.xml.ws.AddressingFeature(true) );

The JAX-WS 2.1 specification indicates that clients must explicitly enable addressing in order to use addressing in a web service that declares support for it. For each invocation, the client must also explicitly set BindingProvider.SOAPACTION_URI_PROPERTY. Example below shows how to use the AddressingFeature class with a service port object to enable WS-Addressing on the client:

import javax.xml.ws.soap.AddressingFeature; public class AddressingClient { public static void main(String...args) { try { // Call Web Service Operation HelloAddressingWSService service = new HelloAddressingWSService(); //enable WS-Addressing HelloAddressingWS port = service.getHelloAddressingWSPort(new AddressingFeature()); String result = port.sayHello("Mikalai"); System.out.println("Result = " + result); } catch (Exception ex) { ex.printStackTrace(); } } }

So all you have to do is create a new AddressingFeature using the default constructor. There are two boolean arguments that you can optionally pass to the constructor as well, indicating preferences for "enabled" and "required":

public AddressingFeature() { this.enabled = true; } public AddressingFeature(boolean enabled) { this.enabled = enabled; } /** * Create an AddressingFeature * * @param enabled specifies whether this feature should * be enabled or not. * @param required specifies whether * WS-Addressing headers MUST be present on incoming messages. This property * only has meaning on the endpoint and has no affect when * used on the client. */ public AddressingFeature(boolean enabled, boolean required) { this.enabled = enabled; Generated by www.PDFonFly.com at 7/24/2012 12:28:02 PM URL: http://java.boot.by/ocewsd6-guide/ch12s02.html this.required = required;

12.2.2. Use Addressing in the deployment descriptors


blah-blah

12.2.3. Use BindingProvider.getEndpointReference()


The BindingProvider interface represents a component that provides a protocol binding for use by clients, it is implemented by proxies and is extended by the Dispatch interface.

Figure 12.1. BindingProvider Class Relationships

A web service client can get an javax.xml.ws.EndpointReference from a BindingProvider instance that will reference the target endpoint. An implementation MUST be able to return an javax.xml.ws.EndpointReference for the target endpoint if a SOAP binding is being used. If the BindingProvider instance has a binding that is either SOAP 1.1/HTTP or SOAP 1.2/HTTP, then a W3CEndpointReference MUST be returned. The returned W3CEndpointReference MUST contain wsam:ServiceName and wsam:ServiceName[@EndpointName] as per Addressing 1.0 Metadata. The wsam:InterfaceName MAY be present in the W3CEndpointReference. If there is an associated WSDL, then the WSDL location MUST be referenced using wsdli:wsdlLocation in the W3CEndpointReference's wsa:Metadata.

12.2.4. Use getPort(EndpointReference) methods.


Proxies provide access to service endpoint interfaces at runtime without requiring static generation of a stub class. See java.lang.reflect.Proxy for more information on dynamic proxies as supported by the JDK. Proxy instances are not guaranteed to be thread safe. If the instances are accessed by multiple threads, usual synchronization techniques can be used to support multiple threads. An instance of a proxy MUST implement javax.xml.ws.BindingProvider. A proxy is created using the getPort methods of a Service instance:
q

T getPort(Class<T> sei) Returns a proxy for the specified SEI, the Service instance is responsible for selecting the port (protocol binding and endpoint address).

Generated by www.PDFonFly.com at 7/24/2012 12:28:02 PM URL: http://java.boot.by/ocewsd6-guide/ch12s02.html

T getPort(QName port, Class<T> sei) Returns a proxy for the endpoint specified by port. Note that the namespace component of port is the target namespace of the WSDL definitions document.

T getPort(Class<T> sei, WebServiceFeature... features) Returns a proxy for the specified SEI, the Service instance is responsible for selecting the port (protocol binding and and endpoint address). The specified features MUST be enabled/disabled and congured as specified.

T getPort(QName port, Class<T> sei, WebServiceFeature... features) Returns a proxy for the endpoint specified by port. Note that the namespace component of port is the target namespace of the WSDL definition document. The specified features MUST be enabled/disabled and congured as specified.

T getPort(EndpointReference epr, Class<T> sei, WebServiceFeature... features) Returns a proxy for the endpoint specified by epr. The address stored in the epr MUST be used during invocations on the endpoint. The epr MUST NOT be used as the value of any addressing header such as wsa:ReplyTo. The specified features MUST be enabled/disabled and configured as specified. Any JAX-WS supported epr metadata MUST match the Service instance's ServiceName, otherwise a WebServiceExeption MUST be thrown. Any JAX-WS supported epr metadata MUST match the PortName for the sei, otherwise a WebServiceException MUST be thrown. If the Service instance has an associated WSDL, its WSDL MUST be used to determine any binding information, any WSDL in a JAXWS suppported epr metadata MUST be ignored. If the Service instance does not have a WSDL, then any WSDL inlined in the JAX-WS supported metadata of the epr MUST be used to determine binding information. If there is not enough metadata in the Service instance or in the epr metadata to determine a port, then a WebServiceException MUST be thrown.

The use of WS-Addressing requirements can be indicated in a WSDL as per Addressing 1.0 - Metadata. A proxy created using getPort() calls is configured with the addressing requirements as specified in the associated WSDL or explicitly passing javax.xml.ws.soap.AddressingFeature web service feature. A proxy MUST be configured with the use of addressing requirements as indicated in the associated WSDL. But if the proxy is created using javax.xml.ws.soap.AddressingFeature web service feature, the feature's addressing requirements MUST take precedence over WSDL's addressing requirements. Client example:

public class Client { @WebServiceRef static AddNumbersService service; private WebServiceFeature[] enabledRequiredwsf = { new AddressingFeature(true, true) }; AddNumbers port; private AddNumbers getPort() { port = service.getPort(AddNumbers.class, enabledRequiredwsf); return port; } ...

Prev Chapter 12. UseWSAddressingwithaSOAPweb service

Up Home

Next Chapter 13. ConfigureMessageLevelsecurityfora SOAPwebservice

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

Generated by www.PDFonFly.com at 7/24/2012 12:28:02 PM URL: http://java.boot.by/ocewsd6-guide/ch12s02.html

Chapter 13. Configure Message Level security for a SOAP web service Prev Part I. Exam Objectives Next

Chapter 13. Configure Message Level security for a SOAP web service
Configure SOAP message-layer security requirements of service as policy assertions in service description; this should be supported by an IDE such as is the case when Netbeans is used to select a Metro Security Profile.

13.1. Select the appropriate Security Profile for your service. The selection would be based on a match of the Protection guarantees offered by the profile and those required by the service.
This first item requires an awareness of the set of security profiles available, and the characteristics of each one - but not enough detail to actually implement a service using any one of them, since not all platforms might support them all.

Prev 12.2. Use Addressing on the client.

Up Home

Next 13.2. Configure Username/Password callbacks required by the Username Token Profile.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

Generated by www.PDFonFly.com at 7/24/2012 12:29:30 PM URL: http://java.boot.by/ocewsd6-guide/ch13.html

13.2. Configure Username/Password callbacks required by the Username Token Profile. Prev Chapter 13. Configure Message Level security for a SOAP web service Next

13.2. Configure Username/Password callbacks required by the Username Token Profile.


blah-blah

Prev Chapter 13. Configure Message Level security for a SOAP web service

Up Home

Next 13.3. Configure any server side Validators as maybe applicable for the profile. There are defaults in GlassFish for most of them.

Hosting provided by PerfoHost: KVM VPS provider. See PefoHost's KVM VPS vs OpenVZ/Virtuozzo vs XEN VPS comparative chart. CRM-exporter: Vehicle Database Script 1999-2011

Generated by www.PDFonFly.com at 7/24/2012 12:30:05 PM URL: http://java.boot.by/ocewsd6-guide/ch13s02.html

S-ar putea să vă placă și