RESTful Web Services with Jersey

7,907 views

Published on

Slides from a mini-talk I recently gave on the Jersey framework for creating/consuming RESTful web services in Java, without hassle.

Published in: Technology, Education
1 Comment
16 Likes
Statistics
Notes
No Downloads
Views
Total views
7,907
On SlideShare
0
From Embeds
0
Number of Embeds
1,575
Actions
Shares
0
Downloads
247
Comments
1
Likes
16
Embeds 0
No embeds

No notes for slide

RESTful Web Services with Jersey

  1. 1. Scott Leberknight RESTful Web Services with Jersey
  2. 2. "Jersey RESTful Web Services framework is [an] open source, production quality framework for developing RESTful Web Services in Java..."
  3. 3. Jersey...
  4. 4. ...produces & consumes RESTful web services (in Java, mostly pain-free)
  5. 5. ...is the JAX-RS reference implementation (and extends JAX-RS with additional features)
  6. 6. JAX-RS? Java API for RESTful Services
  7. 7. It's about the Resources, stupid...
  8. 8. "A JAX-RS resource is an annotated POJO that provides so-called resource methods that are able to handle HTTP requests for URI paths that the resource is bound to."
  9. 9. @Path("/simple") public class SimpleResource { ! @GET @Produces("text/plain") public String get() { return "it's quite simple, you see?"; } } resource class
  10. 10. Root Resources POJO (plain-old Java object) Annotated with @Path and/or method designator (e.g. @GET)
  11. 11. @Path Specifies the URI at which a resource is located URI template capability (via @PathParam)
  12. 12. URI path template @Path("/users/{userid}") @GET @Produces("application/json") public User user(@PathParam("userid") String id) { return _userRepository.getUser(id); }
  13. 13. Method designators Represent the HTTP method that resource methods respond to
  14. 14. @GET @Produces("text/plain") public String get() { return "this is it!"; } HTTP method designator
  15. 15. @Produces Specifies the MIME type of representations that a resource produces
  16. 16. Media Types MediaType class contains constants for common MIME types...
  17. 17. Media Types MediaType.TEXT_PLAIN ! MediaType.APPLICATION_JSON ! MediaType.APPLICATION_XML ! MediaType.MULTIPART_FORM_DATA ! // and more...
  18. 18. @Consumes Specifies the MIME type of representations that a resource can consume
  19. 19. @Consumes @Path("/users") @POST @Consumes(MediaType.APPLICATION_JSON) public Response create(User user) { Long id = _userRepository.create(user); URI uri = URIBuilder.fromURI("/users") .path(id).build(); return Response.created(uri).build(); }
  20. 20. Sub-Resources & Paths methods annotated with @Path in root resource classes, or... methods returning an (annotated) resource class
  21. 21. @Path("/myapp") public class UserResource { // root resource @Path("users") @GET @Produces(MediaType.TEXT_HTML) public String getUsersAsHtml() { ... } ! @Path("users.xml") @GET @Produces(MediaType.APPLICATION_XML) public String getUsersAsXml() { ... } ! @Path("users.json") @GET @Produces(MediaType.APPLICATION_JSON) public String getUsersAsXml() { ... } } Sub-resource methods
  22. 22. Sub-resource URIs /myapp/users /myapp/users.xml /myapp/users.json
  23. 23. Injection Use annotations to specify data to be injected... Query & form parameters Headers, cookies, etc. Security context ...and more
  24. 24. @*Param QueryParam HeaderParam MatrixParam FormParam CookieParam BeanParam
  25. 25. @QueryParam @Path("query-params") @GET public String colors (@QueryParam("red") int red, @QueryParam("green") int green, @QueryParam("blue") int blue) { return String.format("RGB(%d,%d,%d)", red, green, blue); }
  26. 26. @HeaderParam @Path("header-params") @GET public String headers(@HeaderParam("Accept") String accept, @HeaderParam("X-Foo") String foo) { return String.format("Accept: %s, X-Foo: %s", accept, foo); }
  27. 27. @MatrixParam @Path("matrix-params") @GET public String matrixParams(@MatrixParam("red") int red, @MatrixParam("green") int green, @MatrixParam("blue") int blue) { return String.format("RGB(%d,%d,%d)", red, green, blue); }
  28. 28. What's a "matrix param"? http://www.w3.org/DesignIssues/MatrixURIs.html Also, see Tim-Berners Lee on matrix param design issues circa 1996... acme.com/rest/samples/color;red=25;green=78;blue=192 Parameters separate by semi-colons, e.g. Not widely used, supported (or known)
  29. 29. What if a parameter isn't supplied???
  30. 30. @DefaultValue @Path("defaults") @GET public String defaults( @DefaultValue("Orange") @QueryParam("color") String color, @DefaultValue(MediaType.APPLICATION_JSON) @HeaderParam("Accept") String accept) { ! return String.format("color: %s, Accept: %s", color, accept); }
  31. 31. @FormParam @Path("form-params") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response formParams(@FormParam("first") String firstName, @FormParam("last") String lastName) { ! String entity = String.format("%s %s", firstName, lastName); return Response.ok(entity).build(); }
  32. 32. @BeanParam @Path("bean-params") @POST public Response beanParams(@BeanParam User user) { ! String entity = String.format("User: %s %s", user.getFirstName(), user.getLastName()); return Response.ok(entity).build(); }
  33. 33. @BeanParam class public class User { ! @QueryParam("first") @DefaultValue("John") private String _firstName; ! @QueryParam("last") @DefaultValue("Doe") private String _lastName; ! public String getFirstName() { return _firstName; } ! public String getLastName() { return _lastName; } }
  34. 34. @Context Use to obtain information related to request/response
  35. 35. UriInfo @Path("context-uri-info/{thing}") @GET public String uriInfo(@Context UriInfo info) { URI baseUri = info.getBaseUri(); MultivaluedMap<String, String> queryParams = info.getQueryParameters(); MultivaluedMap<String, String> pathParams = info.getPathParameters(); ! return String.format("base URI: %s, query params: %s, path params: %s", baseUri, queryParams.entrySet(), pathParams.entrySet()); }
  36. 36. HttpHeaders @Path("http-headers") @GET public String httpHeaders(@Context HttpHeaders headers) { List<MediaType> acceptableMediaTypes = headers.getAcceptableMediaTypes(); String xFoo = headers.getHeaderString("X-Foo"); ! return String.format("acceptableMediaTypes: %s, X-Foo: %s", acceptableMediaTypes, xFoo); }
  37. 37. Raw form parameters @Path("raw-form") @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response rawForm(MultivaluedMap<String, String> formParams) { ! String entity = formParams.entrySet().toString(); return Response.ok(entity).build(); } (Note: don't actually need @Context in above)
  38. 38. Resource Life Cycle
  39. 39. Scopes Per-Request (default) new instance created on each request Per-lookup new instance created on each lookup (perhaps within same request) Singleton only one instance for entire app
  40. 40. JAX-RS Application Model
  41. 41. Defines components of a JAX-RS application, i.e. resources Application class Independent of deployment environment JAX-RS apps provide concrete implementation class
  42. 42. Simple Application public class SampleApplication extends Application { ! @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<>(); ! classes.add(SampleResource.class); classes.add(SimpleResource.class); classes.add(UserResource.class); ! return classes; } }
  43. 43. Jersey's implementation of Application Jersey ResourceConfig Extend or create programmatically Provides additional features like resource classpath scanning
  44. 44. Jersey ResourceConfig public class SampleJerseyApp extends ResourceConfig { ! public SampleJerseyApp() { // scan classpath for resources packages("com.acme.rest", "com.foo.services"); ! // register filters register(CsrfProtectionFilter.class); register(UriConnegFilter.class); register(HttpMethodOverrideFilter.class); ! // other configuration, etc. } }
  45. 45. Deployment Options
  46. 46. JavaSE (e.g. Grizzly, Jetty, Simple, etc.) Servlet container (e.g. Tomcat, Jetty) JavaEE (e.g. JBoss, etc.) OSGi
  47. 47. Using Grizzly HTTP Server (JavaSE deployment)
  48. 48. public class Server { public static final String BASE_URI = "http://localhost:8080/rest/"; ! public static HttpServer startServer() { ResourceConfig config = new ResourceConfig() .packages("com.acme.rest") .register(CsrfProtectionFilter.class) .register(UriConnegFilter.class) .register(HttpMethodOverrideFilter.class); ! // create a new Grizzly HTTP server rooted at BASE_URI return GrizzlyHttpServerFactory .createHttpServer(URI.create(BASE_URI), config); } ! public static void main(String[] args) throws Exception { final HttpServer server = startServer(); System.out.printf("Jersey app started with WADL available at " + "%sapplication.wadlnHit enter to stop it...n", BASE_URI); System.in.read(); server.shutdownNow(); } } Grizzly Server
  49. 49. Client API
  50. 50. Jersey provides a client API to consume RESTful services Written in fluent-style (method chaining) Supports URI templates, forms, etc.
  51. 51. Client client = ClientBuilder.newClient(); WebTarget target = client.target("http://localhost:8080/rest") .path("sample/query-params"); String response = target.queryParam("red", 0) .queryParam("green", 113) .queryParam("blue", 195) .request() .get(String.class); Client API example
  52. 52. Representations
  53. 53. ...supports common media types like JSON, XML, etc. ...implementations provide ways to convert to/from various media representations JAX-RS...
  54. 54. ...supplies support out-of-box for XML, JSON, etc. ...uses MOXy as the default provider for JSON and XML conversion Jersey...
  55. 55. @Path("/") public class UserResource { ! @Path("/users.json") @GET @Produces(MediaType.APPLICATION_JSON) public Collection<User> users() { return _userRepository.getAllUsers(); } ! @Path("/users/{userid}.json") @GET @Produces(MediaType.APPLICATION_JSON) public User user(@PathParam("userid") Integer id) { return _userRepository.getUser(id); } ! @Path("/users.json") @POST @Consumes(MediaType.APPLICATION_JSON) public Response create(User user) throws Exception { Long id = _userRepository.save(user); URI uri = UriBuilder.fromUri("users").path(id).build(); return Response.created(uri).build(); } ! // more resource methods... } Automatic JSON support
  56. 56. Building Responses @POST @Consumes("application/xml") public Response post(String content) {   URI createdUri = buildUriFor(content);   String createdContent = create(content);    return Response.created(createdUri) .entity(Entity.text(createdContent)).build(); }
  57. 57. & more to explore...
  58. 58. Security JerseyTest Asynchronous API Filters & Interceptors Bean Validation MVC templates ...and more (see Jersey user guide)
  59. 59. References https://jersey.java.net Jersey web site https://jersey.java.net/documentation/latest/index.html Jersey user guide (latest) https://grizzly.java.net/ Project Grizzly web site https://jersey.java.net/apidocs/latest/jersey/index.html Jersey API docs https://jax-rs-spec.java.net JAX-RS web site
  60. 60. My Info twitter: sleberknight www.sleberknight.com/blog scott dot leberknight at gmail dot com

×