Вы находитесь на странице: 1из 44

WEB SERVICES

Sam Guinea
guinea@elet.polimi.it
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)
Lets 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
Lets 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 <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:
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
<?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 players 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 doesnt 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


Handler<C extends
MessageContext>
boolean handleMessage (C context)
boolean handleFault (C context)
void close (MessageContext context)

LogicalHandler<C extends
LogicalMessageContext>

SOAPHandler<C extends
SOAPMessageContext>
Set<QName> 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 <String, Object>

MessageContext
Enum Scope

LogicalMessageContext
LogicalMessage getMessage()

SOAPMessageContext
Object[] getHeader(...)
Set<String> 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 lets 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 clients side and the log

should be saved to a local file.

Вам также может понравиться