JAX-WS • Java API for XML-Web Services • The reference framework for Java Web Services • Bundled into the Metro Web Services Stack
• Part of the Glassfish Application Server but… • Also available in the core Java Standard Edition 6.
@WebService
@WebService(targetNamespace = "http://duke.org", name="AddNumbers") public interface AddNumbersIF extends Remote { @WebMethod(operationName="add", action="urn:addNumbers") @WebResult(name="return") public int addNumbers( @WebParam(name="num1")int number1, @WebParam(name="num2")int number2) throws RemoteException, AddNumbersException;
@WebMethod
@WebService(targetNamespace = "http://duke.org", name="AddNumbers") public interface AddNumbersIF extends Remote { @WebMethod(operationName="add", action="urn:addNumbers") @WebResult(name="return") public int addNumbers( @WebParam(name="num1")int number1, @WebParam(name="num2")int number2) throws RemoteException, AddNumbersException;
@WebParam
@WebService(targetNamespace = "http://duke.org", name="AddNumbers") public interface AddNumbersIF extends Remote { @WebMethod(operationName="add", action="urn:addNumbers") @WebResult(name="return") public int addNumbers( @WebParam(name="num1") int number1, @WebParam(name="num2") int number2) throws RemoteException, AddNumbersException;
@WebResult
@WebService(targetNamespace = "http://duke.org", name="AddNumbers") public interface AddNumbersIF extends Remote { @WebMethod(operationName="add", action="urn:addNumbers") @WebResult(name="return") public int addNumbers( @WebParam(name="num1") int number1, @WebParam(name="num2") int number2) throws RemoteException, AddNumbersException;
@SOAPBinding
@WebService(targetNamespace = "http://duke.org", name="AddNumbers") @SOAPBinding(style=SOAPBinding.Style.RPC, use=SOAPBinding.Use.LITERAL) public interface AddNumbersIF extends Remote { @WebMethod(operationName="add", action="urn:addNumbers") @WebResult(name="return") public int addNumbers( @WebParam(name="num1")int number1, @WebParam(name="num2")int number2) throws RemoteException, AddNumbersException;
@RequestWrapper @ResponseWrapper
@WebMethod @WebResult(targetNamespace = "") @RequestWrapper(localName = "addNumbers", targetNamespace = "http:// server.fromjava/",
className = "fromjava.client.AddNumbers") @ResponseWrapper(localName = "addNumbersResponse", targetNamespace = "http://
server.fromjava/", className = "fromjava.client.AddNumbersResponse") public int addNumbers( @WebParam(name = "arg0", targetNamespace = "”) int arg0, @WebParam(name = "arg1", targetNamespace = "”) int arg1) throws AddNumbersException_Exception;
WS Programming • Defining the SEI (Service Endpoint Interface)
• Marked with @WebService • Declaring the methods which are the web service operations.
• Marked with @WebMethod
• Implementing the SIB (Service Implementation Bean) • Defining the methods declared in the SEI.
• Publishing the WS: • With core Java 6 • With Application Server (Glassfish)
• Let’s see a first example…
Time Server • TimeServer is the SEI • TimeServerImpl is the SIB
• A Java Application to publish the WS (TimeServerPublisher)
• Testing the WS: • With a Browser • With SOAPUI
• Client Programming
• Publishing the service ( and the associated wsdl ) • In the src directory: wsimport -keep -p eser1.tsClient http://127.0.0.1:9877/ts?wsdl • Easily create the tsClientFromWSDL Let’s see how…
TimeServer Client with wsimport
GlassFish • An open source application server. • Provides a fully-featured implementation of Java EE 6:
• JAX-WS • JAX-RS • JAXB • EJB
• Web Container: • deploys servlets and web services.
• Message-oriented middleware: • supporting JMS (Java Message Service).
• RDBMS (Relational Database Management System) • much more…
Apt (Annotation Processing Tool) Usage: apt <apt and javac options> <source files> -d <path> where to place processor and javac generated class files -s <path> where to place processor generated source files -nocompile do not compile source files to class files -print print out textual representation of specified types -factorypath <path> where to find annotation processor factories -factory <class> name of AnnotationProcessorFactory to use;
Wsimport
wsimport [options] <WSDL_URI> -b <path> specify jaxws/jaxb binding files or additional schemas -d <directory> specify where to place generated output files -keep keep generated files -p <pkg> specifies the target package -s <directory> specify where to place generated source files
.war files • Web Application archive file. • Standard structure to respect:
web deployment descriptor
jax-ws deployment descriptor
AppName
WEB-INF
META-INF
web.xml
sun-jaxws.xml
classes
SEI service implementation
jax-ws.xml • Service Deployment descriptor:
• specifies where to find the concrete service implementation when a service is invoked.
• name: name of the endpoint • implementation: where to find the SIB • url-pattern: must be equal to the one specified in web.xml
<?xml version="1.0" encoding="UTF-8"?> <endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0"> <endpoint name="MyHello" implementation="hello.HelloImpl" url-pattern="/hello"/>!</endpoints>
web.xml • Web Application deployment descriptor ?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"> <web-app> <listener> <listener-class>com.sun.xml.ws.transport.http.servlet.JAXRPCContextListener</listener-class> </listener> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.JAXRPCServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <session-config> <session-timeout>60</session-timeout> </session-config> </web-app>
Exercise part 1 • Implement a service for exposing soccer team details.
• Use JAXWS annotations to generate and deploy the service
• The service should offer the following two methods: • public Team getTeam(String name); • public List<String> getTeams();
• Team should contain: • The name of the team • A list of players
• Each player should contain: • The name of the player • The number on the player’s shirt.
• Test the service with SOAPUI
Exercise part 2 • Use the WSDL exposed by the service to create a Java
client • Use WSImport
• Use the Java client to print out to System.out • The list of all the teams • The details of the players that play for Spain
MTOM • Message Transmission Optimization Mechanism (W3C)
• Used with XML-binary Optimized Packaging (XOP)
• Alternative to Soap with Attachments
• Efficiency refers to size of the message • SwA: Base64 sends as text encoding leads to 33% increase in size • MTOM: sends in original binary form
ServerSide Just a new Annotation…
@MTOM @WebService(endpointInterface = "server.ImageServer") public class ImageServerImpl implements ImageServer { … }
Client Side • Receiving doesn’t require anything since the WSDL
references an array of bytes…
• Sending needs to be programmatically enabled…
BindingProvider bp = (BindingProvider) service; SOAPBinding binding = (SOAPBinding) bp.getBinding(); binding.setMTOMEnabled(true);
A Simple ImageServer @WebService @SOAPBinding(style = Style.RPC) public interface ImageServer {
@WebMethod Image downloadImage(String name); @WebMethod String uploadImage(Image data, String fileName); @WebMethod List<String> getImageNames();
}
Handlers in JAX-WS • Message interceptors plugged into the JAX-WS runtime. • Both client-side and server-side. • Used to do additional processing of inbound/outbound
messages. • Client/Provider Authentication. • Client/Provider Performance Monitor. • Envelope/HTTP/Payload logging.
Protocol and Logical Handlers
• Protocol Handlers: • may access or change the protocol specific aspects of the
message. • Only SOAPHandler actually available.
• Logical Handlers: • protocol-agnostic. • act only on the payload of the message.
boolean handleMessage (C context)boolean handleFault (C context)void close (MessageContext context)
Handler<C extends MessageContext>
LogicalHandler<C extends LogicalMessageContext>
Set<QName> getHeaders()
SOAPHandler<C extends SOAPMessageContext>
Message Context • A bag of properties shared by:
• client, client run-time, client-side handlers.
• provider, provider run-time, provider-side handlers.
Map <String, Object>
Enum ScopeMessageContext
LogicalMessage getMessage()LogicalMessageContext
Object[] getHeader(...)Set<String> getRoles()
SOAPMessage getMessage()void setMessage(SOAPMessage)
SOAPMessageContext
• Examples of properties: • MESSAGE_OUTBOUND_PROPERTY (Boolean): specifies message
direction. • INBOUND_MESSAGE_ATTACHMENTS (java.Util.Maps): access to the
inbound message attachments. • OUTBOUND_MESSAGE_ATTACHMENTS (java.Util.Maps): access to
the outbound message attachments.
Handlers in practice • Handlers are programmer-written class that contains
callbacks. • Methods invoked by the JAX-WS runtime so that an application has
access to: • the underlying SOAP for SOAPHandlers • the payload for Logical Handlers.
• A Handler can be injected into the handler framework in two steps: • Create a Handler class (implemeting the *Handler interface) with
handleMessage() , handleFault() , close(). getHeaders() (only for SOAPHandler).
• Place a handler within a handler chain. • Through configuration file or code.
The RabbitCounter Example • The RabbitCounter service has one operation
(countRabbits) that computes the Fibonacci numbers. • a SOAP fault is thrown if the argument is a negative integer.
• The service, its clients, and any intermediaries are expected to process SOAP headers: • client injects a header block. • intermediaries and the service validate the information in the
header block. • generating a SOAP Fault if necessary.
• Two ways to throw SOAP faults: • extend the Exception class and throw the exception • throw a fault from a handler.
The RabbitCounter Example • Injecting a Header Block into a SOAP Header.
• FibClient generates a request against the RabbitCounter. • The client-side JWS libraries create a SOAP message that serves
as the request. • The UUIDHandler callbacks are invoked. • The handleMessage callback has access to the whole SOAP
message and injects a UUID (Universally Unique Identifier) value into the header.
Order of execution in handler chain • Typically the top-to-bottom sequence of the handlers in
the configuration file determines the order of execution. • With some exeptions: • For outbound messages handleMessage and
handleFault in LogicalHandler execute before their counterparts in SOAPHandler.
• For inbound messages handleMessage and handleFault in SOAPHandler execute before their counterparts in LogicalHandler.
Example Handler-chain: SH1 LH1 SH2 SH3 LH2
Inbound messages: SH1 SH2 SH3 LH1 LH2
Outbound messages: LH1 LH2 SH1 SH2 SH3
Configuring the Client-Side Handler • With a configuration file: In the ws-import generated class FibC.RabbitCounterService simply add the annotation: @HandlerChain(file = "handler-chain.xml") • Or you can add the handler programmatically:
SEE FibClientHR
SOAP Fault • In handler.fib.RabbitCounter a customized exception that
the @WebMethod countRabbits throws if it is invoked with a negative integer as argument.
• SOAP Message:
Adding a Logical Handler to the Client • To avoid the fault let’s add to the client the LogicalHandler
ArgHandler that: • intercepts the outgoing requests. • check the argument to countRabbits • change the argument if it is negative.
• It uses a JAXBContext to extract the payload ( in this case the body of the outgoing SOAP message).
• Get – Check - Change - Set the arg0 (the argument of CountRabbits).
• Add ArgHandler in the handler-chain
Adding a Service-Side SOAP Handler • To complete the example we need a service-side SOAP
handler to process the header block and throw a fault if needed.
• see UUIDValidator
UEFA European League • Requirements:
• Implement a Java Application which prints to the console: • All the city names where games are played • All the players of all the qualified teams • All the strikers of the Italian Team
• The data source is provided as a web-service. • You can find the WSDL at:
http://footballpool.dataaccess.eu/data/info.wso?WSDL
Exercise part 3 • Change the teams service to use the data exposed by the
following UEFA European League web service
• http://footballpool.dataaccess.eu/data/info.wso?WSDL
Top Related