WEB SERVICES - Politecnico di Milano

44
WEB SERVICES Sam Guinea [email protected] http://servicetechnologies.wordpress.com/

Transcript of WEB SERVICES - Politecnico di Milano

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

• 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

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

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

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

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.