Java Web Services

46 downloads 163 Views 778KB Size Report
Java Web Services: Up and Running, 1st Edition ... The reference framework for Java Web Services ... Also available in the core Java Standard Edition 6.
WEB SERVICES Sam Guinea [email protected] http://servicetechnologies.wordpress.com/

Reference Book Martin Kalin Java Web Services: Up and Running, 1st Edition O'Reilly Media, Inc.

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

TimeServer Client with wsimport •  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…

SERVICES IN GLASSFISH

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 -d where to place processor and javac generated class files -s 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 where to find annotation processor factories -factory name of AnnotationProcessorFactory to use;

Wsimport wsimport [options] -b specify jaxws/jaxb binding files or additional schemas -d specify where to place generated output files -keep keep generated files -p specifies the target package -s specify where to place generated source files

.war files •  Web Application archive file. •  Standard structure to respect: AppName

WEB-INF

web deployment descriptor

web.xml

jax-ws deployment descriptor

sun-jaxws.xml

classes

SEI

META-INF

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 !

web.xml •  Web Application deployment descriptor ?xml version="1.0" encoding="UTF-8"?> com.sun.xml.ws.transport.http.servlet.JAXRPCContextListener hello com.sun.xml.ws.transport.http.servlet.JAXRPCServlet 1 hello /hello 60

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 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

BINARY DATA

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 getImageNames(); }

HANDLERS

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 Handler boolean handleMessage (C context) boolean handleFault (C context) void close (MessageContext context)

LogicalHandler

SOAPHandler Set getHeaders()

•  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.

Message Context •  A bag of properties shared by: •  client, client run-time, client-side handlers. •  provider, provider run-time, provider-side handlers.

Map

MessageContext Enum Scope

LogicalMessageContext LogicalMessage getMessage()

SOAPMessageContext Object[] getHeader(...) Set getRoles() SOAPMessage getMessage() void setMessage(SOAPMessage)

•  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.

handler-chain.xml

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

LAB EXERCISES

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

Exercise part 4 •  Implement a SOAP handler that timestamps and logs all

the requests made to the service •  Logging should occur on the client’s side and the log

should be saved to a local file.