Jersey Async REST

Source: https://github.com/span/jersey

Versions

  • Jersey 1 uses com.sun.jersey
  • Jersey 2 uses org.glassfish.jersey.*
  • Make sure you know which version you are using

Grizzly

  • Jersey does not require servlet framework
  • Grizzly HTTP container can be used
  • Grizzly is a framework using Java NIO API
  • Divided into Core Framework and HTTP Services

HTTP vs. Servlet Containers

  • Servlet Container uses War file with web.xml file and source
  • HTTP Container uses a Main classto launch rest of source and deploys in Jar
  • Lots of other containers can be used (jetty, jdk, simple http, tomcat)

Generating starter project

  • Use Maven archetype

  • Generates Plain Old Resource (MyResource.java)

  • Generates Main.java with resource config elements

ResourceConfig

  • Scans for components using packages() and files()
  • Register custom JAX-RS componenets with register()
  • Get and set application properties

Simple example

Testing with JerseyTest

  • Leverages existing jersey components
  • JerseyTest provide both Container and Client
  • Tests use the client to invoke API’s deployed in container
  • Important methods:
    • configure()
    • configureClient()
    • target()
    • enable()

Configuring Container and Client

Invoking an endpoint

Example tests

Test properties

  • It is possible to configure features and properties when running tests

Dependency injection and POST support

  • Using the @Context annotation
  • Many different Classes available for injection

  • Using HK2 to add to @Context and inject our own objects

  • Requires a Binder registered with ResourceConfig

Async requests

  • @ManagedAsync and @Suspended are commonly used annotations

  • Grizzly Threads receives request -> Passes on to Jersey Async Threads

  • Databases (or other Applications) may provide their own async interfaces

  • Application Threads can be combined with Jersey Async Threads

  • AsyncResponse can be used in many different ways

  • Guava can be used in DAO to give it an asynchronous interface

  • URI invoked -> Resource method -> DAO method | ListenableFuture.onSuccess(stuff) <-|

  • Collections and Concurrent hashmaps may cause issues using the built-in Moxy JSON support

  • Good thing we can use Jackson instead!

Jackson

  • Jackson can process data (json, xml etc.)
  • Register in resource config
  • Watch out for format changes on dates, enums, properties etc.
  • Has many annotations and configs for changing behaviour and formats

  • Jackson can store arbitrary elements that are submitted using annotations

  • Adding XML support

  • Prioritize json over xml

  • Other XML annotations

MessageBodyWriter

  • Converts Java type to Stream
  • Can be used to format json and xml differently
  • Uses isWrtieable to determine which MBW to use

Bean Validation, Exceptions and Conditional GET

  • Beans can be validated with Annotations
  • Hibernate Validator is used in Jersey
  • Setup in pom.xml and can be configured in resource config
  • Possible to write custom ValidationConfig class

  • Validate using @Valid and @NotNull annotations

  • Possible to map Exceptions to Responses

  • Use EntityTags to support “If-None-Match” and conditional GETs

  • Use ResponseBuilder to build() response to client

  • ResponseBuild can set any header (cache, cookie, encoding, links, last modified etc.)

PATCH support

  • Extend Jerseys supported HTTP verbs with PATCH
  • Can be used through a custom annotation
  • Needs a custom client connector like Grizzly’s

  • Can be extended by supporting the If-Match header

  • Uses evaluatePreconditions as conditional GETs

  • The caller supply an entity tag which must match the servers

  • If not, it’s assumed the servers tag has changed

Filters in Jersey

  • Supports JAX-RS filters
  • Can modify requests and responses
  • Pre-Matching Request Filter
    • Applied to incoming request before method is selected
  • Post-Matching Request Filter
    • Applied after Resource method is selected but before execution
  • Response Filter
    • Applied after Resource method
  • Filters need modification to use async functionality, runs in Grizzly Thread by default
  • Can use Name Binding to control usage of filters

Filters vs Interceptors

  • Filters
    • Modify headers, entity and other request/response params
    • Executed regardless of wheter there is an entity to read/write
    • Can abort a request and prevent resource method from executing
  • Interceptor

    • Primarily to manipulate the entity
    • Can change properties to affect choice of Message Body Reader/Writer
    • Only executed if there is an entity to read/write
  • Execution Order

    1. Pre-Match filters
    2. Post-Match filters
    3. Reader Interceptor
    4. Response Filter
    5. Writer Interceptor
  • Jersey Filters

    • Logging
    • JAX-RS to Spring Request attribute bridge
    • CSRF protection

    • HTTP method overrides

    • URI-based content negotiation

Custom filters

  • Possible to write custom request/response filters
  • Can use annotations to decide which type of request filter
  • Implements a filter method

  • Use name binding to choose when filter is applied

    1. Define a name binding annotation

    2. Associate annotation with filter or interceptor

    3. Use annotation to flag a resource method (or application)