The presentation provides overview of JAX-RS 2.0 and the cool new things that come with it. It also provides an introduction to OData which is a protocol proposed by Microsoft for data interchange.
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
JAX-RS 2.0 and OData
1. JAX-RS 2.0 AND ODATA
Anil Allewar ( anil.allewar@synerzip.com )
2. About Me
Graduated (finally) as BE in Computers - 2002
Worked with Infosys, Opus Software Solutions
and Synerzip
Currently working as Solutions Architect with
Synerzip
Core expertise in Java Enterprise and Middle-
Ware stack
EAI, EII, Rule Engines, ESB, Spring, ORM, Data
Virtualization
3. Agenda
REST methodology introduction
JAX-RS 2.0
History
Use cases
Features
Odata
History
Use cases
Features
4. SOA
Service Oriented Architecture is an
architecture paradigm where the software
components are provided as services
accessed through a network accessible
endpoint
There is no object broker required as
there is no remote object reference held
Registry
by the client Registers
Defines Format
Protocol & Operations Contract
5. What is REST?
REST stands for REpresentational State Transfer.
The largest example of system conforming to
REST architecture is the World Wide Web.
In the REST architectural style, data and
functionality are considered resources and are
accessed using Uniform Resource Identifiers
(URIs), typically links on the Web.
This architecture style is called REST since the
state of the client changes with each URI (link in
layman’s term) accessed. The URI provides the
representation that is returned by the resource.
Resources are manipulated using a fixed set of
four CRUD (create, read, update, delete)
operations: PUT, GET, POST and DELETE
Current version of JAX-RS in production is JAX-RS
1.1 and JAX-RS 2.0 is currently being drafted.
6. JAX-RS
JAX-RS is Java API for RESTful Web Services
REST principals
Assign URL to everything
Link things together for state transition(called
HyperMedia as the engine of application state)
Use common methods
Multiple representations of state
Stateless communication
Introduced in JEE 5
7. Pros/Cons: JAX-WS Vs JAX-
RS
JAX-WS JAX-RS
• Formal contract that describes the • Does not require creation of
web service (in the form of WSDL) is client/server proxies
available • Requires only HTTP for
• Technologies defined by the World application protocol - data
Wide Web Consortium (W3C): HTTP (for interchange using XML, HTML,
Transport protocol), SOAP and WSDL JSON,URL encoded forms etc
• Implemented either using an EJB 3 • Implemented as a servlet
endpoint or using servlet endpoint. endpoint only
• Can provide transactions, security, • Possible to discover resources
Reliability and asynchronous messages without centralized repository
• Requires client/server proxies to • Service provider and client need
make the SOAP based web service call to have understanding of the
context and content provided by
service (Not now as WSDL 2.0 /
WADL / XML schema can be
used to describe REST web service)
but
they don’t have standard client
support
8. JAX-RS annotations
Annotation Description
@Path The @Path annotation defines the relative path where the web service
is hosted. You could also embed variables in path like “/employee/{id}.
A @Path value isn’t required to have leading or trailing slashes (/).
The path can be applied to a root resource or to a sub-resource.
@GET, @POST These annotations are request method designators and correspond to
@DELETE, @PUT HTTP request method that will be serviced by this class method
The @PathParam annotation is a type of parameter that you can
@PathParam extract from the URI path and use in the class/method
@QueryParam The @QueryParam annotation is a type of parameter that you can
extract from the request URI query parameters and use in the
class/method
@Consumes The @Consumes annotation is used to specify the MIME types of
representations sent by the client that a resource can consume.
@Produces The @Produces annotation is used to specify the MIME types of
representations sent by the resource to the client e.g. “application/xml”
9. Basic REST Web Service
@Path("rest")
public class RootResource {
/*
Resource
* The @Context makes the HTTP context related objects available to the s
* resource class
*/
@Context
private transient SecurityContext secContext;
Dependenc
@Context
private transient HttpServletRequest request; y Injection
@Inject
private Provider<BaseProducer> producer;
@Path("employee")
public EmployeeResource getEmployeeResource() {
this.request.setAttribute("test", "Memory");
EmployeeResource returnResource = new EmployeeResource(); HTTP
returnResource.setContext(this.secContext);
producer.get(); Method
return returnResource;
} Binding
@GET
@Produces({ "application/xml; qs=0.9", MediaType.APPLICATION_JSON })
public String sayXMLHello() {
return "<?xml version="1.0"?>" + "<hello> Hello Jersey" + "</hello>";
}
}
10. Web Deployment Descriptor
There are various ways in which we can have Jersey discover the
resources to be deloyed.
For simple deployments, no web.xml is needed at all. Instead, an
@ApplicationPath annotation can be used to annotate the user defined
application class and specify the the base resource URI of all application
resources.
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>JAXRS_REST_WebServices</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.anil.jaxb.resource.config.ApplicationConfigSetter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
11. Basic Jersey Client
/**
* This method is used to test get/delete request for an employee to the
* REST API API
*
* @throws IOException
*/
@Test
public void testDeleteEmployeeRequest() throws IOException {
WebTarget webResource = this.client.target(getBaseURI()).path(
"rest/employee/3");
// Register the authentication to be used for logging in the web
// application
webResource.configuration().register(
new HttpBasicAuthFilter("tomcat", "tomcat"));
String getResponse = webResource.request(MediaType.APPLICATION_XML)
.get(String.class);
String deleteResponse = webResource.request(MediaType.APPLICATION_XML)
.delete(String.class);
System.out.println("The response received from get is: " + getResponse);
System.out.println("The response received from delete is: "
+ deleteResponse);
}
12. Web Service Security
Since REST web services are essentially HTTP resources, they can be
protected using the Java EE web authentication and authorization
mechanism using elements in web.xml file.
<!-- The web resources with root /rest are protected -->
<security-constraint>
<web-resource-collection>
<web-resource-name>REST</web-resource-name>
<url-pattern>/rest/employee/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<!-- Use the tomcat-users.xml for authentication -->
<role-name>tomcat</role-name>
</auth-constraint>
</security-constraint>
<!-- Define the Login Configuration for this Application -->
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>UserDatabaseRealm</realm-name>
</login-config>
<!-- Security roles referenced by this web application -->
<security-role>
<description>The unlimited role allowed to login to the application.</description>
<role-name>tomcat</role-name>
</security-role>
13. Sub-resource Locators
We can delegate the handling of request to sub resources by using
methods annotated with @Path BUT not annotated with resource method
designators such as @GET or @POST.
Note that the runtime will not manage the life-cycle or perform any field
injection onto instances returned from sub-resource locator methods.
However, sub-resources support method injection.
@Path("rest")
public class RootResource {
.............
@Path("employee")
public EmployeeResource getEmployeeResource() {
this.request.setAttribute("test", "Memory");
EmployeeResource returnResource = new EmployeeResource();
returnResource.setContext(this.secContext);
return returnResource;
}
}
14. Exceptions, URIBuilder, JAXB
Based JSON support
JAX-RS provides exceptions to be thrown which
match to HTTP error codes; examples include
javax.ws.rs.NotFoundException,
javax.ws.rs.ServerErrorException
The JAX-RS runtime provides URIBuilder class which
takes care of specifics like encoding etc which you
would need to otherwise do manually for java.net.URI
class.
JAXB/JSON support is provided by using custom
Message readers and writers.
Custom
@Produces(MediaType.APPLICATION_XML) Serialization
public Response insertEmployee(final Employee employee, for JAXB
@Context UriInfo uriInfo) {...........}
15. Injecting Types
We can define fields/method params etc to be injected
with object of the described type by the JAX-RS
runtime.
Injection can be performed on fields, constructor
parameters, resource/sub-resource/sub-resource
locator method parameters and bean setter methods.
For JAX-RS 1.1, @Context annotation was used to
indicate injectables to JAX-RS runtime.
JAX-RS 2.0 has integrated with JSR-330 (CDI) and
Jersey supports CDI using HK2. You can use
@Context or @Inject though @Context is still
preferred.
The proposal for this area is not finalized yet in JAX-
RS 2.0 specifications
16. JAX-RS 2.0 features
Asynchronous
Filters &
Client API Processing
handlers
Validation CDI (JSR-
Hypermedia
(JSR-349) 330)
Server Side
Connection
Negotiation
17. Client API
The JAX-RS 1.1 specifications was focussed
on server side and there was no client API.
Need for a standard to also share server side
API(readers/writer) and encapsulate boiler
plate code
Client Client
Factory
Configuratio
Request n
Builder
Respon
se Target
Invocati
on
18. Client API
Create a new client (This is heavy!!)
this.client = ClientFactory.newClient();
Use builder pattern to invoke server resources
– supports adding query params, target
entitieswebResource = this.client.target(getBaseURI()).path(
WebTarget
etc.
"rest/employee");
// Register the authentication to be used for logging in the web
// application
webResource.configuration().register(
new HttpBasicAuthFilter("tomcat", "tomcat"));
Response response = webResource.request(MediaType.APPLICATION_XML).put(
Entity.entity(employeeToAdd, MediaType.APPLICATION_XML),
Response.class);
Close the client after use.
19. Client API
Support for generic invocation using command
pattern for batch processing
Invocation invGoodRequest = this.client
.target(getBaseURI())
.path("rest/employee")
.request(MediaType.APPLICATION_XML)
.buildPut(Entity.entity(inputXMLBuilder.toString(),
MediaType.APPLICATION_XML));
invGoodRequest.configuration().register(
new HttpBasicAuthFilter("tomcat", "tomcat"));
Collection<Invocation> invCollection = Arrays.asList(invGoodRequest,
invBadRequest);
// Execute the invocation as a batch process
for (Invocation currentInvocation : invCollection) {
// By default invoke() returns a response but we also have an
// overloaded method that takes the target class as parameter
Response response = currentInvocation.invoke();
}
20. Filters and Handlers
Message request pre-processing and response post-
processing via well-defined extension points on the
client and server side.
Use cases – logging, stream marshalling(Gzip etc),
security
Filters
Each filter can decide to continue or break the chain
Filters in the filter chain are ordered according to their
binding priority
The binding priority is an annotation that specifies an
integer based priority
You can match what filters are applied to what resources –
default is global
Do not directly invoke the next filter in the chain – hence is
called Non wrapping filter chain
Filters implementing this interface must be annotated with
21. Filters and Handlers
@Provider
@Logging
@BindingPriority(1)
public class LoggingFilter implements ContainerRequestFilter,
ContainerResponseFilter {
private static Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
/*
* @see
* javax.ws.rs.container.ContainerResponseFilter#filter(javax.ws.rs.container
* .ContainerRequestContext, javax.ws.rs.container.ContainerResponseContext)
*/
@Override
public void filter(ContainerRequestContext reqContext,
ContainerResponseContext responseContext) throws IOException {
logger.info("POST request filter for server and the response entity class is: "
+ responseContext.getEntity().getClass().getCanonicalName());
}
/*
* @see
* javax.ws.rs.container.ContainerRequestFilter#filter(javax.ws.rs.container
* .ContainerRequestContext)
*/
@Override
public void filter(ContainerRequestContext reqContext) throws IOException {
logger.info("PRE request filter for server: "
+ reqContext.getRequest().toString());
}
}
23. Filters and Handlers
Handlers are wrapping i.e. It directly invokes the
next handler in the handler chain
Typically used for message data marshalling and
un-marshalling
By default handlers are global but mechanism is
provided for static(@NameBinding) as well as
dynamic binding(DynamicBinding interface) of a
filter or handler to a particular resource or
resource method
Typically used to say compress streams
API still work in progress
24. Asynchronous Messaging
Server API support
Execute long running server processes
Frees up container threads to service other
requests
By default remain suspended till the server event
completes
Resume operation once the server event is
generated
Client API support
Asynchronous request invocation API
25. Asynchronous Messaging -
Server
public static final String NOTIFICATION_RESPONSE = "Hello async world!";
private static final Logger LOGGER = LoggerFactory.getLogger(HelloResource.class.getName());
private static final int SLEEP_TIME_IN_MILLIS = 1000;
private static final ExecutorService TASK_EXECUTOR = Executors.newCachedThreadPool(new
ThreadFactoryBuilder().setNameFormat("long-running-resource-executor-%d").build());
private static int count = 0;
/**
* Asyc method server support
* * @param asyncResponse
*/
@Path("async")
@GET
public void longGet(@Suspended final AsyncResponse asyncResponse) {
TASK_EXECUTOR.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(SLEEP_TIME_IN_MILLIS);
LOGGER.debug("Received request for async processing: "
+ HelloResource.count++);
} catch (InterruptedException ex) {
LOGGER.error("Response processing interrupted", ex);
}
asyncResponse.resume(NOTIFICATION_RESPONSE);
}
});
}
26. Asynchronous Messaging -
Client
@Test
public void testAsyncClientRequests() throws InterruptedException {
Client client = ClientFactory.newClient();
WebTarget webResource = client.target(getBaseURI()).path("hello/async");
final int REQUESTS = 10;
final CountDownLatch latch = new CountDownLatch(REQUESTS);
for (int i = 0; i < REQUESTS; i++) {
webResource.request(MediaType.TEXT_PLAIN).async()
.get(new InvocationCallback<Response>() {
@Override
public void completed(Response response) {
try {
final String result = response
.readEntity(String.class);
Assert.assertEquals("Hello Jersey", result);
} finally {
latch.countDown();
}
}
@Override
public void failed(ClientException exception) {
System.out.println("Exception while invocation: "
+ exception.getMessage());
latch.countDown();
}
});
}
}
27. Validation
Services need to validate data before processing
Bean Validation is a Java specification which:
provides a unified way of declaring and defining constraints
on an object model.
defines a runtime engine to validate objects
Already have JSR 349: Bean Validation 1.1 which
needs to be integrated to JAX-RS
Support for constraint annotations in
Methods (response entities)
Fields & properties
Parameters (in request entity)
Resource classes
28. Validation
@POST Default
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_XML)
public String searchEmployee(@NotNull @FormParam("name") String name,
@OrderNumber @FormParam(“orderNumber") String orderNumber,
@FormParam(“department") String department) {
@Constraint(validatedBy = OrderNumberValidator.class)
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
Custom
public @interface OrderNumber {
String message() default "{custom message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class OrderNumberValidator implements ConstraintValidator<OrderNumber, String> {
/** Configure the constraint validator based on the elements specified at the time it
was defined. */
public void initialize(OrderNumber constraint) {
...
}
/** Validate a specified value. returns false if the specified value does not
conform to the definition */
public boolean isValid(String value, ConstraintValidatorContext context) {
//validate value
}
}
29. HyperMedia
Use HATEOAS (Hypermedia As The Engine Of
App State) REST principle
Structural links are used to avoid sending a
complete representation of a resource and enable
lazy loading. The clients can follow these type of
links to retrieve the "pieces" they need.
Transitional link is used to update the state of a
resource and is typically identified by a "rel"
attribute.
Structural links are normally in the entity;
transitional links could be in link headers or the
entity.
Support transitional links only
30. Improved Connection
Negotiation
This would allow a server to specify a
preferred MIME type if the client does not care
about it.
An unspecified value takes the default value of
1
The rule says "application/json" will be served
as the preferred type if there is no Accept
@GET
@Produces({ "application/xml; qs=0.9", MediaType.APPLICATION_JSON })
header from the client.
@Logging
public String sayXMLHello() {
return "<?xml version="1.0"?>" + "<hello> Hello Jersey" + "</hello>";
}
31. WADL/WSDL 2.0
The Web Application Description Language
(WADL) is a machine-readable XML description of
HTTP-based web applications (typically REST
web services).
REST doesn’t really require description; follow
links
Additionally because the WADL generates
machine readable code, it would break when the
interface changes – tight coupling
WSDL 2.0 adds supports for REST services
Sample WADL available at http://odata4j-
sample.appspot.com/datastore.svc/application.wa
dl
32. Odata - Introduction
Open Data Protocol (OData) is a Web protocol
for querying and updating data
Based on Web technologies such as HTTP, Atom
Publishing Protocol (AtomPub) and JSON
The OData Protocol is different from other REST-
based web service approaches in that it provides
a uniform way to describe both the data and the
data model
The current version of Odata specifications is
version 3; however the java implementation for
OData (called OData4j) supports version 2
OData4j will move to version 3 after release 1.0;
currently at 0.7
33. ATOM
Atom is an XML-based document format that
describes lists of related information known as
"feeds“
Feeds are composed of a number of items, known
as "entries", each with an extensible set of
attached metadata
The "atom:entry" element represents an individual
entry, acting as a container for metadata and data
associated with the entry.
It can be child of an atom:feed element OR it can
be the top level element
34. ATOM Example
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"> XML
<title>Example Feed</title> Namespace
<link href="http://example.org/"/>
<updated>2003-12-13T18:30:02Z</updated> ATOM
<author> feed
Metadata
<name>John Doe</name>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
<entry>
<title>Atom-Powered Robots Run Amok</title>
<link href="http://example.org/2003/12/13/atom03"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-
Entry 80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>
35. Odata Structure
Feed
Metadata (title, id, updated etc)
Collection of entries
Entry
Properties (primitives & complex)
Links (related entries and related feeds)
Service document that lists all the top level feeds – usually
serviced by the service root URI endpoint
OData services can also expose Service Operations, which
are simple, service-specific functions that accept input
parameters and return entries or complex/primitive values.
The data is usually serviced by a producer who can expose
data from relational databases, web services etc
The producer takes care of transformation between EDM and
the underlying data access layer
36. EDM
Entity Data Model (EDM) - is the underlying abstract
data model used by OData services to formalize the
description of the resources it exposes
All data services may also expose a Service Metadata
Document that describes the data model (i.e. structure
and organization of all the resources) exposed as
HTTP endpoints by the service.
Metadata is available at the endpoint using convention
$metadata
The central concepts in the EDM are entities and
associations.
EDM is defined using an XML language called
conceptual schema definition language (CSDL)
37. EDM
EntityTypes – data model definitions(for example
customer, product etc)
Entities – instances of Entity types with a key and
structured type consisting of list of properties
Complex Types - structured types also consisting
of a list of properties but with no key
Entity Key – primary key either single or
composite
Associations - define the relationship between
two or more Entity Types
Navigation Properties - special properties on
Entity Types which are bound to a specific
association and can be used to refer to
associations of an entity
38. OData Producers
Create a factory that OData4j can use to
initialize the producer
OData4j currently supports JPAProducer &
InMemoryProducer. It also plans to support
JDBCProducer in the near future.
You can write your own producer and it has to
implement the
org.odata4j.producer.ODataProducer
interface.
40. URI Convention
URI Used for Example
$links Get all associations between http://localhost:8080/odata_exampl
entries e/odatajpa.svc/SupplierParts(1L)/$
links/part
$orderby Order data based on desc or http://localhost:8080/odata_exampl
asc (default) options e/odatajpa.svc/SupplierParts?$ord
erby=quantity desc
$top Return first N items of the set http://localhost:8080/odata_exampl
e/odatajpa.svc/SupplierParts?$ord
erby=quantity desc&$top=4
$skip Skip the first N records of the http://localhost:8080/odata_exampl
entity set and get next e/odatajpa.svc/SupplierParts?$ski
p=2&$top=2
$filter Select only subset of entities http://localhost:8080/odata_exampl
that match the predicates e/odatajpa.svc/SupplierParts?$filte
provided – rich set of operators r=(quantity gt 200 and quantity lt
and functions 300) or shipperId eq 10
41. URI Convention
URI Used for Example
$expand Eagerly load associations http://localhost:8080/odata_example/
inline odatajpa.svc/Supplier?$expand=supp
lierParts
$format Specify what media type http://localhost:8080/odata_example/
to be used for odatajpa.svc/Supplier?$expand=supp
response(Atom/Xml/Json lierParts&$format=Json
)
$select Return only subset of http://localhost:8080/odata_example/
properties odatajpa.svc/Supplier?$select=suppli
erCity, supplierId
$inlinec Response should include http://localhost:8080/odata_example/
ount the count on entities after odatajpa.svc/Supplier?$inlinecount=al
applying $filter. Valid lpages
values are <m:count>16</m:count>
allpages/none
42. CUD Operations using
Consumer
// create the new product
OEntity newSupplier = consumer.createEntity("Supplier")
.properties(OProperties.string("supplierId", "S200"))
.properties(OProperties.string("supplierName", "Smith A"))
.properties(OProperties.string("supplierCity", "Boston"))
.properties(OProperties.string("supplierState", "MA"))
.properties(OProperties.decimal("supplierStatus", 20L))
.execute();
// update the newly created product
consumer.updateEntity(newSupplier)
.properties(OProperties.string("supplierName", "Carl A"))
.execute();
report("newSupplier name after update: "
+ consumer.getEntity("Supplier", "S200").execute()
.getProperty("supplierName").getValue());
// update the newly create product using merge
consumer.mergeEntity("Supplier", "S101")
.properties(OProperties.string("supplierName", "Zack A"))
.execute();
report("newPart rating after merge: "
+ consumer.getEntity("Supplier", "S101").execute()
.getProperty("supplierName").getValue());
// clean up, delete the new product
consumer.deleteEntity("Supplier", "S200").execute();
43. Batch Operations
Odata supports executing multiple operations
sent in a single HTTP request through the use
of Batching
The batch requests can be sent as POST with
the path containing $batch
OData Batch Request is represented as a
Multipart MIME v1.0 message
The OData4j implementation is inefficient in
the sense that it executes the individual batch
items in a separate transaction
JAX-WS - Java API for XML Web ServicesJAX-RS - Java API for RESTful Web Services Additional pointsJAX-RS is lighter on bandwidth as you do not need to wrap each request/response with SOAP envelope.JAX-RS API calls are easier to make for anyone with event basic HTTP knowledge; SOAP requires SOAP toolkit to form requests and parse results.As for authentication and authorization, SOAP places the burden in the hands of the application developer. The REST methodology instead takes into account the fact that Web servers already have support for these tasks. Another point with regards to security is what operations to monitor for blocking; in case of RESTful web services you can allow only GET method call (typically idempotent) specifically on port 80. For SOAP, you need to allow POST requests which can modify the state on the server.SOAP provides relatively stronger typing since it has a fixed set of supported data types.
Other annotations@FormParam - The @FormParam annotation is a type of parameter that you can extract from the request form that is submitted and used in the class/method. This parameter is very useful for extracting information sent by POST in HTML forms. @CookieParam - Extract information from the cookies declared in cookie-related HTTP headers @Context – Provides context related objects like URIInfo, Request, Response and SecurityContext@DefaultValue– The default value to use if some parameter is not available
System Query Options are query string parameters a client may specify to control the amount and order of the data that an OData service returns for the resource identified by the URI. The names of all System Query Options are prefixed with a "$" character.
Custom Query Options provide an extension point for OData service-specific information to be placed in the query string portion of a URI.