JAX-RS 2.0 and OData


Published on

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.

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • 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.
  • JAX-RS 2.0 and OData

    1. 1. JAX-RS 2.0 AND ODATAAnil Allewar ( anil.allewar@synerzip.com )
    2. 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. 3. Agenda REST methodology introduction JAX-RS 2.0  History  Use cases  Features Odata  History  Use cases  Features
    4. 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. 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. 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. 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. 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. 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. 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. 11. Basic Jersey Client/** * This method is used to test get/delete request for an employee to the * REST API API * * @throws IOException */@Testpublic 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. 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. 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. 14. Exceptions, URIBuilder, JAXBBased 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. 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. 16. JAX-RS 2.0 features Asynchronous Filters & Client API Processing handlers Validation CDI (JSR- Hypermedia (JSR-349) 330) Server Side Connection Negotiation
    17. 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. 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. 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. 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. 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()); }}
    22. 22. Filters and Handlers@Target({ ElementType.TYPE, ElementType.METHOD })@Retention(value = RetentionPolicy.RUNTIME)@NameBindingpublic @interface Logging {}@GET@Produces({ "application/xml; qs=0.9",MediaType.APPLICATION_JSON })@Loggingpublic String sayXMLHello() { return "<?xml version="1.0"?>" + "<hello> Hello Jersey" + "</hello>";}
    23. 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. 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. 25. Asynchronous Messaging -Serverpublic 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")@GETpublic 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. 26. Asynchronous Messaging -Client@Testpublic 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. 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. 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) Custompublic @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. 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. 30. Improved ConnectionNegotiation 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. 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. 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. 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. 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> feedMetadata <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. 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. 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. 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. 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.
    39. 39. Registering Producerpublic class ODataJPAProducerFactory implements ODataProducerFactory { private String persistenceUnitName = "odataJPAService"; private Strig namespace = "odataJPA"; private int maxResults = 50; Inject Producer @Override public ODataProducer create(Properties arg0) { EntityManagerFactory emf = Persistence .createEntityManagerFactory(persistenceUnitName); JPAProducer producer = new JPAProducer(emf, namespace, maxResults); return producer; }}<servlet> <servlet-name>OData</servlet-name> Register <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> Producer <param-value>org.odata4j.jersey.producer.resources.ODataApplication</param-value> </init-param> <init-param> <param-name>odata4j.producerfactory</param-name> <param-value>com.synerzip.odata.producer.ODataJPAProducerFactory</param-value> </init-param> <load-on-startup>1</load-on-startup></servlet>
    40. 40. URI ConventionURI 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. 41. URI ConventionURI 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. 42. CUD Operations usingConsumer// create the new productOEntity 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 productconsumer.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 mergeconsumer.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 productconsumer.deleteEntity("Supplier", "S200").execute();
    43. 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
    44. 44. Questions?
    45. 45. References JAX-RS 2.0  http://jersey.java.net/nonav/documentation/snaps hot/index.html  http://bitworking.org/news/193/Do-we-need- WADL  http://www2008.org/papers/pdf/p805- pautassoA.pdf  http://docs.oracle.com/javaee/6/tutorial/doc/giepu. html OData  http://www.odata.org/documentation/IndexV2  http://code.google.com/p/odata4j/