REST Migration to jsr311
The new implementation of the REST engine respects the jsr311 specification.
1 REST service structure:
- REST service must be represented by Java class that has @Path annotation, it calls root resource. In some cases class may have not @Path, about this classes see in Sub-Resource Locators section. Root resource class may contain Resource Methods, Sub-Resource Methods and Sub-Resource Locators. Root resource MUST contain at least one of it.
- Resource Method it is method that contains HTTP method annotation, e.g. @GET, @POST, etc. and it does not contain @Path annotation.
- Sub-Resource Method it is method that contains HTTP method annotation and @Path annotation.
- Sub-Resource Locator it is method that does not contain HTTP method annotation but contains @Path annotation. Sub-Resource Locator can't process request directly but it can produce Object (Resource) and that object can process request or has Sub-Resource Locator that can produce other Resource.Other important part @Consumes and @Produces annotations. These annotations can be used at classes and methods. Annotation on method override annotation on class.
- Annotated method parameters @PathParam, @QueryParam, @FormParam, @HeaderParam, @Matrix, @CookieParam, @Context annotation must be (Description of this annotation in jsr311 specification or jsr311-api javadoc):
- String
- Primitive type, except char
- Has constructor with single string arguments
- Has static valueOf method with single string argument
- Be List, Set or SortedSet with items described in first four points
- Not annotated method parameter or Entity Parameter.
- Must be not more then one
- Sub-Resource Locator MUST NOT have Entity Parameter.
- If Resource Method or Sub-Resource Method contains at least one parameter with @FormParam annotation then Entity Parameter MUST be MultivaluedMap<String, String> only.
- Method return type. Resource method (Resource Method or Sub-Resource Method) may return void,javax.ws.rs.core.Response,javax.ws.rs.core.GenericEntity or other Java type. If void type returned ot returned object is null then 204 HTTP status will be set for response otherwise 200 status will be used. With javax.ws.rs.core.Response response can be set by service developer.
- Reading/Writing Entity done via EntityProvider. Each EntityProvider can require precise preset media type of entity, for example JsonEntityProvider require 'Content-Type' and/or 'Accept' header set as application/json. REST engine supports next entity provider:
| Provider class | Media Type | Java Type |
|---|
| ByteEntityProvider | */* | byte[] |
| DataSourceEntityProvider | */* | javax.activation.DataSource |
| DOMSourceEntityProvider | application/xml,application/xhtml+xml,text/xml | javax.xml.transform.dom.DOMSource |
| FileEntityProvider | */* | java.io.File |
| MultivaluedMapEntityProvider | application/x-www-form-urlencoded | MultivaluedMap<String, String> |
| MultipartFormDataEntityProvider | multipart/* | java.util.Iterator<org.apache.commons.fileupload.FileItem> |
| InputStreamEntityProvider | */* | java.io.InputStream |
| ReaderEntityProvider | */* | java.io.Reader |
| SAXSourceEntityProvider | application/xml,application/xhtml+xml,text/xml | javax.xml.transform.sax.SAXSource |
| StreamSourceEntityProvider | application/xml,application/xhtml+xml,text/xml | javax.xml.transform.stream.StreamSource |
| StringEntityProvider | */* | java.lang.String |
| StreamOutputEntityProvider | */* | NOTE for writing data only |
| JsonEntityProvider | application/json | Object (simple constructor, get/set methods) |
| JAXBElementEntityProvider | application/xml,application/xhtml+xml,text/xml | javax.xml.bind.JAXBElement |
| JAXBObjectEntityProvider | application/xml,application/xhtml+xml,text/xml | Object (simple constructor, get/set methods) |
2 Migration Examples
2.1 Migration example 1
Old code
package org.exoplatform.services.rest.example;
import org.exoplatform.services.rest.HTTPMethod;
import org.exoplatform.services.rest.URITemplate;
import org.exoplatform.services.rest.URIParam;
import org.exoplatform.services.rest.container.ResourceContainer;
import org.exoplatform.services.rest.transformer.StringOutputTransformer;
import org.exoplatform.services.rest.OutputTransformer;
import org.exoplatform.services.rest.Response;
@URITemplate("/a/{1}/b")
public class Resource implements ResourceContainer {
@HTTPMethod("GET")
@URITemplate("{2}")
@OutputTransformer(StringOutputTransformer.class)
public Response m0(@URIParam("1") String param1, @URIParam("2") String param2) {
Response resp = Response.Builder.ok(param1+param2, "text/plain").build();
return resp;
}
}
New code
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam
@Path("/a/{1}/b")
public class Resource implements ResourceContainer {
@GET
@Path("{2}")
@Produces("text/plain")
public String m0(@PathParam("1") String param1, @PathParam("2") String param2) {
return path1+path2;
}
}
2.2 Migration example 2
Old code
import org.exoplatform.services.rest.HTTPMethod;
import org.exoplatform.services.rest.InputTransformer;
import org.exoplatform.services.rest.Response;
import org.exoplatform.services.rest.URITemplate;
import org.exoplatform.services.rest.container.ResourceContainer;
import org.exoplatform.ws.frameworks.json.transformer.Json2BeanInputTransformer;
public class Resource implements ResourceContainer {
@HTTPMethod("POST")
@URITemplate("/")
@InputTransformer(Json2BeanInputTransformer.class)
public Response m0(Book book) {
// do something with bean
return Response.Builder.noContent().build();
}
}
New code
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Consumes;
@Path("/")
public class Resource implements ResourceContainer {
@POST
@Consumes("application/json")
public void m0(Book book) {
// do something with bean
}
}
3 Support for javax.ws.rs.core.Application
Since version exo-ws-2.0.1 add support for class javax.ws.rs.core.Application. It gives possibility to setup services and provider life-cycle to singleton or per-request mode. For details see JAX-RS specification, chapter 2. Subclass of Application should be configured as component of exo-container.