Wednesday, March 23, 2016

Jersey 2.x



https://www.logicbig.com/tutorials/java-ee-tutorial/jax-rs/filters-pre-matching.html
In JAX-Rs, filters can be divided into two categories: pre-matching filters and post-matching filters.
A post-matching filter is applied only after a suitable resource method has been selected to process the request. Such filters can not influence the resource method matching process. We have seen such filter example in the last tutorial.
A pre-matching filter (annotated with @RequestMatching) is executed before the request matching process is started. This filter can influence which resource method will be matched e.g. by changing the HTTP method or by changing the URI etc.
http://stackoverflow.com/questions/17143514/how-to-add-custom-response-and-abort-request-in-jersey-1-11-filters
In case of error, if you want to send a custom response then you need to throw a WebApplicationException. Create a Response object and send it back using the following exception constructor:
WebApplicationException(Response response) 
          Construct a new instance using the supplied response
Try this:
@Override
public ContainerRequest filter(ContainerRequest request) {
    User user = Helper.getCurrentUser();
    if(user == null){
        ResponseBuilder builder = null;
        String response = "Custom message";
        builder = Response.status(Response.Status.UNAUTHORIZED).entity(response);
        throw new WebApplicationException(builder.build());

    }
    return request;
}

http://stackoverflow.com/questions/35906403/jersey-containerrequestfilter-getting-404-after-throwing-abortwith-with-statu
requestContext.abortWith(Response.status(Response.Status.FORBIDDEN).build());

https://jersey.java.net/documentation/latest/filters-and-interceptors.html



It's a good practice to assign a priority to filters and interceptors. Use Priorities class which defines standardized priorities in JAX-RS for different usages, rather than inventing your own priorities. So, when you for example write an authentication filter you would assign a priority 1000 which is the value of Priorities.AUTHENTICATION. The following example shows the filter from the beginning of this chapter with a priority assigned.
http://jmchung.github.io/blog/2013/08/11/cross-domain-on-jersey-restful-web-services/
@OPTIONS public Response myResource() { return Response.ok().build(); }

   @OPTIONS
   @Path("/myresource")
   public Response corsMyResource(@HeaderParam("Access-Control-Request-Headers") String requestH) {
      _corsHeaders = requestH;
      return makeCORS(Response.ok(), requestH);
   }
https://simplapi.wordpress.com/2013/04/10/jersey-jax-rs-implements-a-cross-domain-filter/
You need to escape all options, so at the beginning of the filter, add like this (see from methods.equals(« OPTIONS »)) :
@Override
public ContainerRequest filter(ContainerRequest containerRequest) throws WebApplicationException {
    //GET, POST, PUT, DELETE, ...
    String method = containerRequest.getMethod();
    // myresource/get/56bCA for example
    String path = containerRequest.getPath(true);
    if(method.equals("OPTIONS")) {
        throw new WebApplicationException(Status.OK);
    }
http://www.codingpedia.org/ama/how-to-add-cors-support-on-the-server-side-in-java-with-jersey/


https://java.net/jira/browse/JERSEY-2553
http://www.developerscrappad.com/2308/java/java-ee/rest-jax-rs/java-rest-jax-rs-2-0-how-to-handle-date-time-and-timestamp-data-types/
public class RESTTimestampWithTZDParam {
    private SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZ" );
    private java.util.Date date;
    public RESTTimestampWithTZDParam( String dateTimeStr ) throws WebApplicationException {
        try {
            date = new java.util.Date( df.parse( dateTimeStr ).getTime() );
        } catch ( final ParseException ex ) {
            throw new WebApplicationException( ex );
        }
    }
    public java.util.Date getDate() {
        return date;
    }
    @Override
    public String toString() {
        if ( date != null ) {
            return date.toString();
        } else {
            return "";
        }
    }
}
https://www.mkyong.com/webservices/jax-rs/jax-rs-queryparam-example/
@QueryParam("orderBy") List<String> orderBy
URI Pattern : “users/query?from=100&to=200&orderBy=age&orderBy=name
 public Response getUsers(@Context UriInfo info) {

  String from = info.getQueryParameters().getFirst("from");
  String to = info.getQueryParameters().getFirst("to");
  List<String> orderBy = info.getQueryParameters().get("orderBy");
http://stackoverflow.com/questions/6154861/handling-multiple-query-parameters-in-jersey
If you change the type of your item method parameter from String to a collection such as List<String>, you should get a collection that holds all the values you are looking for.
The JAX-RS specification (section 3.2) says the following regarding the @QueryParam annotation:
The following types are supported:
  1. Primitive Types
  2. Types that have a constructor that accepts a single String argument.
  3. Types that have a static method named valueOf with a single String argument.
  4. List<T>Set<T>, or SortedSet<T> where T satisfies 2 or 3 above.
List<String> items=ui.getQueryParameters().get("item");
where ui is declared as a member in the rest resource like so :
@Context UriInfo ui;

Some libs like axios js use the square brackets notation when sending a multi-value param request: /stats?store[]=A&store[]=B&item[]=C&item[]=D

To handle all cases (with or without square brackets) you can add another param like this:
public String methodImCalling(
  @QueryParam(value = "store") final List<String> store, 
  @QueryParam(value = "store[]") final List<String> storeWithBrackets, 
  @QueryParam(value = "item") final List<String> item,
  @QueryParam(value = "item[]") final List<String> itemWithBrackets) {
...
}
http://kingsfleet.blogspot.com/2014/01/selecting-level-of-detail-returned-by_29.html

https://jersey.java.net/documentation/latest/entity-filtering.html

http://blog.dejavu.sk/2014/02/04/filtering-jax-rs-entities-with-standard-security-annotations/
    @DenyAll
    public String getSecret() { ... }

    @RolesAllowed({"manager", "user"})
    public List<Task> getTasks() { ... }

    @RolesAllowed({"manager"})
    public List<User> getUsers() { ... }

    @RolesAllowed({"manager", "client"})
    public List<Report> getReports() { ... }

http://blog.dejavu.sk/2015/02/04/jerseys-entity-filtering-meets-jackson/
@GET
@Path("{id}")
public Person getPerson() {
    // ...
    return person;
}
And for people/1234?select=familyName,givenName,addresses.phoneNumber.number the response would be:

{
   "addresses":[
      {
         "phoneNumber":{
            "number": "867-5309"
         }
      }
   ],
   "familyName": "Dowd",
   "givenName": "Andrew"
}

@Path("projects")
@Produces("application/json")
public class ProjectsResource {
    @GET
    public List<Project> getProjects() {
        return getDetailedProjects();
    }
    @GET
    @Path("detailed")
    @ProjectDetailedView
    public List<Project> getDetailedProjects() {
        return EntityStore.getProjects();
    }
}

http://howtodoinjava.com/jersey/jersey-selectable-entityfilteringfeature-example/
you want to make RESTful API consumers capable of filtering data what they need from a GET API, rather than forcing them to consume all the response data unnecessary. There are two ways to achieve this filtering : server side response filtering and client side response filtering.

To demonstrate the use of client side response filtering using SelectableEntityFilteringFeature,


public class CustomApplication extends ResourceConfig
{
    public CustomApplication()
    {
        packages("com.howtodoinjava.jersey");
        // Configure MOXy Json provider. Comment this line to use Jackson. Uncomment to use MOXy.
        // register(new MoxyJsonConfig().setFormattedOutput(true).resolver());
        // Configure Jackson Json provider. Comment this line to use MOXy. Uncomment to use Jackson.
        register(JacksonFeature.class);
         
        register(SelectableEntityFilteringFeature.class);
        property(SelectableEntityFilteringFeature.QUERY_PARAM_NAME, "select");
    }

}
If you want to enable this feature through web.xml file, then you can add the feature to the list of provider class names:
<init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>
        org.glassfish.jersey.filter.LoggingFilter,
        org.glassfish.jersey.message.filtering.SelectableEntityFilteringFeature,
        org.glassfish.jersey.jackson.JacksonFeature
    </param-value>
</init-param>
And for setting the query selector property, use the below code:

<init-param>
    <param-name>jersey.config.entityFiltering.selectable.query</param-name>
    <param-value>select</param-value>
</init-param>


  1. Hit HTTP GET: http://localhost:8080/JerseyDemos/rest/employees?select=employeeList,id

    Response:
    {"employeeList":[{"id":1},{"id":2},{"id":3}]}

Spring MVC is a full Web frontend framework including support for HTML and other templating, plus other features, in addition to the JSON/XML REST features provided by Jersey.
Jersey first runs ExceptionMapper then ContainerResponseFilter
http://www.makeinjava.com/execution-flow-filters-interceptors-jax-rs-jersey-example/

[[FATAL] No injection source found for a parameter of type public
-- this means jersey can not map something to your parameter

Jersey can map string to complex PathParam, but you need follow some rules.

Method register(class, priority) is not retaining the default priority
https://java.net/jira/browse/JERSEY-2640

http://stackoverflow.com/questions/34639434/why-jersey-doesnt-honor-the-priorities-in-dynamically-bind-filters
Try to use javax.annotation.Priority annotations instead of the 2nd parameter in FeatureContext::register and ResourceConfig::register calls, which overrides the annotation.
@Priority(1)
public class MyDynamicFilter implements ContainerRequestFilter {
...
@Priority(2)
public class MyStaticFilter implements ContainerRequestFilter {
https://jersey.java.net/documentation/latest/filters-and-interceptors.html#d0e10129
. So, a request filter with priority defined with @Priority(1000) will be executed before another request filter with priority defined as @Priority(2000). Providers used during response processing (ContainerResponseFilterClientResponseFilter) are executed in the reverse order (using descending manner), so a provider with the priority defined with @Priority(2000) will be executed before another provider with priority defined with @Priority(1000).
http://stackoverflow.com/questions/26989608/jersey-2-3-setting-priority-for-containerrequestfilter
Use the @Priority for your filter classes, passing in a value (e.g. @Priority(1)). The lower the number, the higher the priority (Don't need for anything special in web.xml or Application subclass)
@Priority(6000)
public class MyFilter1 ... {}

@Priority(6001)
public class MyFilter2 ... {}

Option 2:

Configure it programmatically into the application via an inject-able Configurable. Something like
@ApplicationPath("/")
public class MyApplication extends Application {
    public MyApplication(@Context Configurable configurable) {
        configurable.register(MyFilter1.class, 1000);
        configurable.register(MyFilter2.class, 1001);
    }
}
https://servicesunavailable.wordpress.com/2014/05/23/jersey-filters-containerrequestfilter-and-containerresponsefilter/

https://jersey.java.net/documentation/latest/filters-and-interceptors.html
Interceptors share a common API for the server and the client side. Whereas filters are primarily intended to manipulate request and response parameters like HTTP headers, URIs and/or HTTP methods, interceptors are intended to manipulate entities, via manipulating entity input/output streams. If you for example need to encode entity body of a client request then you could implement an interceptor to do the work for you.

Context is specific to a particular request but instances of certain JAX-RS components (providers and resource classes with a lifecycle other than per-request) may need to support multiple concurrent requests. When injecting an instance of one of the types listed in Section 9.2, the instance supplied MUST be capable of selecting the correct context for a particular request. Use of a thread-local proxy is a common way to achieve this.
So, as per the specification, JAX-RS implementations (e.g. Jersey) are required to ensure that the context is safe. Keep doing what you're doing.
You're safe. When you're injecting HttpServletRequest / HttpServletResponse you're not dealing with a particular instance but rather with a proxy through which you're invoking calls on a real instance stored in a ThreadLocal object. Each request is processed by a separate thread which has access to it's own HttpServletRequest / HttpServletResponse. Beside injecting HttpServletRequest / HttpServletResponse you can also inject ThreadLocal<HttpServletRequest> / ThreadLocal<HttpServletResponse> and through '#get()` method you can obtain the real request / response instances intead of proxies.
Customize QueryParam/PathParam
https://github.com/javaee-samples/javaee7-samples/blob/master/jaxrs/paramconverter/src/main/java/org/javaee7/jaxrs/paramconverter/MyBeanConverterProvider.java
@Provider
public class MyBeanConverterProvider implements ParamConverterProvider {

    @Override
    public &lt;T&gt; ParamConverter&lt;T&gt; getConverter(Class&lt;T&gt; clazz, Type type, Annotation[] annotations) {
        if (clazz.getName().equals(MyBean.class.getName())) {

            return new ParamConverter&lt;T&gt;() {

                @SuppressWarnings("unchecked")
                @Override
                public T fromString(String value) {
                    MyBean bean = new MyBean();
                    bean.setValue(value);
                    return (T) bean;
                }

                @Override
                public String toString(T bean) {
                    return ((MyBean) bean).getValue();
                }

            };
        }
        return null;
    }

}

http://stackoverflow.com/questions/29207562/how-to-use-custom-type-for-pathparam
The thing is path parameters come in String form. As per the specification, if we want the have a custom type be injected as a @PathParam, the custom class, should have one of three things:
  1. A public static valueOf(String param) that returns the type
  2. A public static fromString(String param) that returns the type
  3. Or a public constructor that accepts a String
  4. Another option implement a ParamConverter. You can see an example here.
If you don't own the class (it's a third-party class that you can't change) then your only option is to use the ParamConverter/ParamConverterProvider pair.
In either of these cases you'll want to construct the instance accordingly by parsing the String either in the constructor or in one of the above mentioned methods. After doing this, the custom type can be made a method parameter with the annotation.
The same holds true for other params, such as @FormParam@HeaderParam@QueryParam, etc.
http://stackoverflow.com/questions/30403033/passing-custom-type-query-parameter
Take a look at the @QueryParam documentation, in regards to acceptable types to inject. (The same applies to all the other @XxxParam annotations also)
  1. Be a primitive type
  2. Have a constructor that accepts a single String argument
  3. Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String))
  4. Have a registered implementation of ParamConverterProvider JAX-RS extension SPI that returns a ParamConverter instance capable of a "from string" conversion for the type.
  5. Be List<T>Set<T> or SortedSet<T>, where T satisfies 2, 3 or 4 above. The resulting collection is read-only.
The reason for these requirements is that the value comes in as a string. The runtime needs to know how to convert a string to the type to inject. The reason for the exception is that there is an initial resource model validation on startup. This validation checks to make sure all your injection points are valid. It sees that the injected type MyRequest doesn't meet any of the above requirements, and throws an exception.
Basically you with points 2 and 3, you will need to parse the string yourself, for instance
public class MyRequest {
    public static MyRequest fromString(string param) {
        // 1. Parse string
        // 2. Create MyRequest request;
        return request;
    }

http://blog.dejavu.sk/2014/02/11/inject-custom-java-types-via-jax-rs-parameter-annotations/
ParamConverterProvider and ParamConverter. With the first one we simply tell the runtime whether we’re able to convert String to a particular type and with the second one we’re doing the actual conversion.

 JAX-RS 2.0 implementations have to support the following types:
  1. Primitive types.
  2. Types that have a constructor that accepts a single String argument.
  3. Types that have a static method named valueOf or fromString with a single String argument that return an instance of the type. If both methods are present then valueOf MUST be used unless the type is an enum in which case fromString MUST be used.
  4. List<T>Set<T>, or SortedSet<T>, where T satisfies 2 or 3 above.
This basically tells us that when there are only a few classes which we want to inject it’s sufficient to create static methods fromString /valueOf in these classes (or make sure the classes have a constructor which accepts one string argument) and we can use them as injection targets.
http://stackoverflow.com/questions/31612687/jackson-jsondeserialize-not-being-called-for-queryparam
MessageBodyReaders aren't used for @QueryParam. You seem to be expecting the Jackson MessageBodyReader to handle this deserialization, but it doesn't work like that.
Instead you will want to use a ParamConverter, which will need to be registered through a ParamConverterProvider.
@Provider
public class LocalDateParamConverterProvider implements ParamConverterProvider {

    final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");

    @Override
    public <T> ParamConverter<T> getConverter(
            Class<T> rawType, Type genericType, Annotation[] antns) {

        if (LocalDate.class == rawType) {
            return new ParamConverter<T>() {
                @Override
                public T fromString(String string) {
                    try {
                        LocalDate localDate = LocalDate.parse(string, formatter);
                        return rawType.cast(localDate);
                    } catch (Exception ex) {
                        throw new BadRequestException(ex);
                    }
                }

                @Override
                public String toString(T t) {
                    LocalDate localDate = (LocalDate) t;
                    return formatter.format(localDate);
                }
            };
        }

        return null;
    }
}

http://docs.oracle.com/javaee/6/tutorial/doc/gknav.html
subresource locator returns an object that will handle an HTTP request. The method must not be annotated with a request method designator. You must declare a subresource locator within a subresource class, and only subresource locators are used for runtime resource resolution.
The following code snippet shows a subresource locator:
// Root resource class
@Path("/employeeinfo")
public class EmployeeInfo {

    // Subresource locator: obtains the subresource Employee
    // from the path /employeeinfo/employees/{empid}
    @Path("/employees/{empid}")
    public Employee getEmployee(@PathParam("empid") String id) {
        // Find the Employee based on the id path parameter
        Employee emp = ...;
        ...
        return emp;
    }
}

// Subresource class
public class Employee {

    // Subresource method: returns the employee's last name
    @GET
    @Path("/lastname")
    public String getEmployeeLastName() {
        ...
        return lastName
    }
}

HK2
http://www.justinleegrant.com/?p=516
Jersey, by default uses HK2 (aka Hundred Kilobyte Kernel) for Dependency Injection. This was developed by Oracle for the Glassfish Application Server.  HK2 follows the the JSR-330 specification entirely.  What does that mean? It means that this library can be swapped out for another with ease.  So, if you develop with it, just remember that you can swap it out later.  Unfortunately, with Jersey, they are using HK2 for Dependency Injection, so you are forced to either use it, or bridge it with the Spring Bridge or Guice Bridge (there may be others, but those are the most popular DI libraries right now).
@javax.inject.ContractAnnotation to identify interfaces that match a component
@javax.inject.ServiceAnnotation to identify components that can be injected – used for scanning
@javax.inject.InjectInject an instantiated class into an placeholder variable or method
@javax.inject.NamedDifferentiate between different objects of the same type
@javax.inject.QualifierUsed for annotating new annotations (because named annotations are evil)
@javax.inject.ScopeBy placing this annotation, you can tell the injector to retain the instance for possible reuse in a later injection
@javax.inject.SingletonSince HK2 defines that everything is a Prototype, this is necessary for a Singleton instance. Please note, this doesn’t apply when using the @Service annotation (which you should be using most of the time anyways), which is a singleton

Lastly, we need to identify where you need these and apply the @Inject annotation. I advise people to use constructor injection, which ensures all mandatory properties have been satisfied, and it is simply not possible to instantiate an object in an invalid state. Plus, it’s significantly easier to test this way.
https://hk2.java.net/spring-bridge/
http://stackoverflow.com/questions/26230642/jersey-hk2-injecting-service-annotated-classes
we have moved on with the project and eventually gave up on hk2; instead we rely on spring bridge and spring for DI.
https://newfivefour.com/java-jersey-dependency-injection.html

https://github.com/jersey/jersey/tree/master/examples/helloworld-spring-webapp

http://stackoverflow.com/questions/30987153/is-it-possible-to-construct-an-object-partially-with-spring-di-and-partially-wit
It should work. Given you have the required Spring-Jersey integration dependency[1] and have correctly configured the application[2]
What happens is HK2 (Jersey's DI framework) will look for an InjectionResolver for the @Autowired annotation, in order to resolve the dependency. The jersey-spring3 dependency has the AutowiredInjectionResolver, which holds a reference to Spring's ApplicationContext. From there it's just matter of looking it up in the application context, to resolve the dependency.
https://hk2.java.net/2.5.0-b05/introduction.html

https://hk2.java.net/2.5.0-b05/introduction.html
  * Jersey Spring integration example.
  * Demonstrate how to inject a Spring bean into a Jersey managed JAX-RS resource class.

https://blogs.oracle.com/enterprisetechtips/entry/jersey_and_spring
   @Scope("request")
The @Component annotation declares that the class is a Spring bean class. The @Scope("request") annotation declares that instances of this class will be instantiated within the scope of the HTTP request. This highlights a difference between the default scopes for JAX-RS or Jersey and Spring. The default scope for JAX-RS is per request. By comparison, the default scope for Spring is a singleton, that is, one instance per web application. See Supported Scopes for more information about the scopes that Jersey supports.
Jersey supports the following Spring scopes:
  • Request. Scopes a single Spring bean definition to the lifecycle of a single HTTP request, that is, each HTTP request has its own instance of a Spring bean created from a single Spring bean definition. This scope requires that you declare the Spring RequestContextListener servlet context in the web.xml file for the web application.
  • Singleton. Scopes a single Spring bean definition to a single object instance per web application.
  • Prototype. Scopes a single Spring bean definition to multiple object instances. A new Spring bean instance is created for each request for that specific bean.
https://java.net/jira/browse/JERSEY-2055
According to the documentation https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e2030, Table 3.2. and if i remember, in jersey 1.x, the HttpServletRequest can be inject into resource's field directly. but now i only can inject the HttpServletRequest using setter method mode or resource methods mode:
 private @Context HttpServletRequest request; // this will not work
 private @Context HttpServletRequest request2; // valid via setter method

@Context
public void setRequest2(HttpServletRequest request2) {
        this.request2 = request2;
}

@Path("server")
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public AgentConfiguration register(AgentMachine agent, @Context HttpServletRequest request) throws RemoteException
{
   // valid in resource method.
}

http://stackoverflow.com/questions/32574887/purpose-of-component-annotation-on-spring-boot-starter-jersey-resources-in-spri
"To enable JAX-RS resources to work Spring functionality that requires proxying, such as Spring transaction management (with @Transactional), Spring Security and aspect oriented programming (such as @Aspect), the resources must themselves be managed by Spring, by annotating with @Component, @Service, @Controller or @Repository:"
http://stackoverflow.com/questions/26408084/jersey-what-is-the-difference-in-injecting-uriinfo-as-class-instance-variable
Afaig, there is no preferred way for injecting UriInfo. It more or less depends on programming style guidelines you working or not working with. The injection should work while you are working in Jersey-managed components.
I for one, prefer the field injection variant.
Please note: The object you will inject isn't UriInfo itself, it's a proxy pointing on the UriInfo for the current request. You can just picture it as a direct hotline to your container/connector.
The default scope is Request Scoped.
https://jersey.java.net/documentation/latest/ioc.html
Jersey implementation allows you to directly inject HttpServletRequest instance into your JAX-RS components. It is quite straight forward to get the appropriate HttpSessioninstance out of the injected request instance
http://download.oracle.com/otn-pub/jcp/jaxrs-2_0-fr-eval-spec/jsr339-jaxrs-2.0-final-spec.pdf?AuthParam=1464813534_ca389fd17d2b252b377a52c65cb808e5
Chapter 9 Context
@Context UriInfo
@Context HttpHeaders
@Context Request request,
The methods of Request allow a caller to determine the best matching representation variant and to evaluate
whether the current state of the resource matches any preconditions in the request. Precondition support
methods return a ResponseBuilder that can be returned to the client to inform it that the request preconditions
were not met. E.g. the following checks if the current entity tag matches any preconditions in the
request before updating the resource:
. An instance of SecurityContext can be injected into a class field or method parameter using the
@Context annotation

https://jersey.java.net/documentation/latest/jaxrs-resources.html
By default the life-cycle of root resource classes is per-request which, namely that a new instance of a root resource class is created every time the request URI path matches the root resource. This makes for a very natural programming model where constructors and fields can be utilized (as in the previous section showing the constructor of theSparklinesResource class) without concern for multiple concurrent requests to the same resource.
In general this is unlikely to be a cause of performance issues. Class construction and garbage collection of JVMs has vastly improved over the years and many objects will be created and discarded to serve and process the HTTP request and return the HTTP response.
Instances of singleton root resource classes can be declared by an instance of Application.
Request scope@RequestScoped (or none)org.glassfish.jersey.process.internal.RequestScopedDefault lifecycle (applied when no annotation is present). In this scope the resource instance is created for each new request and used for processing of this request. If the resource is used more than one time in the request processing, always the same instance will be used. This can happen when a resource is a sub resource is returned more times during the matching. In this situation only on instance will server the requests.
Per-lookup scope@PerLookuporg.glassfish.hk2.api.PerLookupIn this scope the resource instance is created every time it is needed for the processing even it handles the same request.
Singleton@Singletonjavax.inject.SingletonIn this scope there is only one instance per jax-rs application. Singleton resource can be either annotated with @Singleton and its class can be registered using the instance of Application. You can also create singletons by registering singleton instances into Application.

Class fieldsInject value directly into the field of the class. The field can be private and must not be final. Cannot be used in Singleton scope except proxiable types mentioned above.
Constructor parametersThe constructor will be invoked with injected values. If more constructors exists the one with the most injectable parameters will be invoked. Cannot be used in Singleton scope except proxiable types mentioned above.
Resource methodsThe resource methods (these annotated with @GET, @POST, ...) can contain parameters that can be injected when the resource method is executed. Can be used in any scope.

When deploying a JAX-RS application using servlet then ServletConfigServletContextHttpServletRequest and HttpServletResponse are available using @Context.
http://stackoverflow.com/questions/18914130/when-to-use-singleton-annotation-of-jersey

http://www.theotherian.com/2013/08/jersey-client-2.0-httpclient-timeouts-max-connections.html
The defaults when using HttpClient are as follows:
  • Infinite connection and read timeouts
  • By default when using Jersey's ApacheConnector you will get an instance of BasicClientConnectionManager which limits you to a single connection (though it is thread safe)
  • If you're configuring a PoolingClientConnectionManager instead, you'll have a maximum of 20 total connections with a maximum of 2 connections per host (or route)
To begin, we need to start with a class called ClientConfig. Jersey uses this to configure client instances via its ClientBuilder API. We can set the connection and read timeouts with this class, as shown below:
ClientConfig clientConfig = new ClientConfig();
// values are in milliseconds
clientConfig.property(ClientProperties.READ_TIMEOUT, 2000);
clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 500);

using httpclient with connection pooling
Now let's set up a ClientConnectionManager that uses pooling. We should also set the limits on the number of connections a little bit higher, since 20 total and 2 per host is on the low side (we'll use 100 and 20 instead):

PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
connectionManager.setMaxTotal(100);
connectionManager.setDefaultMaxPerRoute(20);

You can also be much more fine grained about how many connections per host are allowed with the setMaxPerRoute method. For example, let's say it was ok to have 40 max connections when hitting localhost:
connectionManager.setMaxPerRoute(new HttpRoute(new HttpHost("localhost")), 40);

We need to create a new ApacheConnector from the configuration, which specifies the pooled connection manager, and then set the connector in the configuration
ClientConfig clientConfig = ...;
PoolingClientConnectionManager connectionManager = ...;

// tell the config about the connection manager
clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);

// tell the connector about the config, which includes the connection manager and timeouts
ApacheConnector connector = new ApacheConnector(clientConfig);

// tell the config about the connector
clientConfig.connector(connector);
client.register(JacksonFeature.class);

https://blogs.oracle.com/japod/entry/how_to_use_jersey_client
In Jersey 1.x it was suggested to reuse Client instances (see here for details). In Jersey 2, reusing Client instances is still recommended, but as such it is not sufficient to keep things running efficiently. Application performance can easily be undermined here. Related documentation could be found in Jersey User Guide and the key sentence is quoted bellow:
The configuration principles used in JAX-RS client API apply to WebTarget as well.
The documentation does not state this explicitly, so i will write it here in bold once more: be careful when touching configuration of a web target!. What does it mean? Whenever you create a new web target with updated configuration, Jersey will effectively create a new client runtime. To keep your application performing well, you should think of reusing all such web targets.

Tip 2: Avoid WebTarget.register()

If you need to register some extra components, do it on the client already to prevent another client runtime creation. If you need another runtime, just try to register things once and reuse the resulting target instance.

Tip 3: Avoid WebTarget.property()

The same applies to updating properties. These you can happily set on an Invocation or its builder

Tip 4: Use response.close() to release network connections!

When i wrote a simple test to get data for the above graph, i was getting short of available network ports. The problem is well described e.g. here. To avoid this i had to close responses. So as the last tip i recommend you close coming responses as well.
If you are closing 500 connection per second you will run out of sockets. If you are connecting to the same locations (web servers) that use keepalive you can implement connection pools, so you don't close and reopen sockets.
This will save cpu too.
Use of tcp_tw_recycle and tcp_tw_reuse can result in packets coming in from the previous
connecction, that is why there is a 1 minute wait for the packets to clear.
Another important ramification of the ephemeral port range is that it limits the maximum number of connections from one machine to a specific service on a remote machine! The TCP/IP protocol uses the connection's 4-tuple to distinguish between connections, so if the ephemeral port range is only 4000 ports wide, that means that there can only be 4000 unique connections from a client machine to a remote service at one time.
So maybe you run out of available ports. To get the number of available ports, see
$ cat /proc/sys/net/ipv4/ip_local_port_range 
32768   61000
The output is from my Ubuntu system, where I'd have 28,232 ports for client connections. Hence, your test would fail as soon as you have 280+ clients.
Async
https://jersey.java.net/documentation/latest/async.html
Request processing on the server works by default in a synchronous processing mode, which means that a client connection of a request is processed in a single I/O container thread. Once the thread processing the request returns to the I/O container, the container can safely assume that the request processing is finished and that the client connection can be safely released including all the resources associated with the connection. This model is typically sufficient for processing of requests for which the processing resource method execution takes a relatively short time. However, in cases where a resource method execution is known to take a long time to compute the result, server-side asynchronous processing model should be used. In this model, the association between a request processing thread and client connection is broken. I/O container that handles incoming request may no longer assume that a client connection can be safely closed when a request processing thread returns. Instead a facility for explicitly suspending, resuming and closing client connections needs to be exposed. Note that the use of server-side asynchronous processing model will not improve the request processing time perceived by the client. It will however increase the throughput of the server, by releasing the initial request processing thread back to the I/O container while the request may still be waiting in a queue for processing or the processing may still be running on another dedicated thread. The released I/O container thread can be used to accept and process new incoming request connections.

http://blog.dejavu.sk/2015/01/21/intercepting-jersey-resource-method-calls/
http://stackoverflow.com/questions/20556200/jersey-async-containerrequestfilter


https://jersey.java.net/documentation/latest/filters-and-interceptors.html
All the request filters shown above was implemented as post-matching filters. It means that the filters would be applied only after a suitable resource method has been selected to process the actual request i.e. after request matching happens. Request matching is the process of finding a resource method that should be executed based on the request path and other request parameters. Since post-matching request filters are invoked when a particular resource method has already been selected, such filters can not influence the resource method matching process.


To overcome the above described limitation, there is a possibility to mark a server request filter as a pre-matching filter, i.e. to annotate the filter class with the @PreMatchingannotation. Pre-matching filters are request filters that are executed before the request matching is started. Thanks to this, pre-matching request filters have the possibility to influence which method will be matched. Such a pre-matching request filter example is shown here:

@PreMatching
public class PreMatchingFilter implements ContainerRequestFilter {
    @Override
    public void filter(ContainerRequestContext requestContext)
                        throws IOException {
        // change all PUT methods to POST
        if (requestContext.getMethod().equals("PUT")) {
            requestContext.setMethod("POST");
        }
    }
}
As written above, pre-matching filters can fully influence the request matching process, which means you can even modify request URI in a pre-matching filter by invoking thesetRequestUri(URI) method of ContainerRequestFilter so that a different resource would be matched.

http://howtodoinjava.com/jersey/jersey-2-hello-world-application-tutorial/

http://stackoverflow.com/questions/25701658/integrating-jersey-2-and-spring-with-java-based-configuration

https://jersey.java.net/documentation/latest/spring.html
If you want to use Jersey Spring DI support you will need to add the jersey-spring3 module into the list of your dependencies:
1
2
3
4
5
<dependency>
    <groupId>org.glassfish.jersey.ext</groupId>
    <artifactId>jersey-spring3</artifactId>
    <version>2.22.2</version>
</dependency>
https://github.com/jersey/jersey/tree/2.22.2/examples/helloworld-spring-webapp
<servlet>
    <servlet-name>SpringApplication</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>org.glassfish.jersey.examples.helloworld.spring.MyApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

http://www.theotherian.com/2013/07/creating-resource-filters-with-jersey.html
public class IE6NotSupportedFilter implements ContainerRequestFilter {

  @Override
  public void filter(ContainerRequestContext requestContext) throws IOException {
    if (isIE6Browser(requestContext.getHeaderString("User-Agent"))) {
      requestContext.abortWith(Response.status(Status.PRECONDITION_FAILED).entity(getFailurePage()).build());
    }
  }
}
Now that we have an annotation, a filter, and a way to link the filter to a resource, we need to tell our application to invoke this upon startup.
http://blog.dejavu.sk/2013/11/19/registering-resources-and-providers-in-jersey-2/

@ApplicationPath("/")
public class MyApplication extends ResourceConfig {

    public MyApplication() {
        // Register resources and providers using package-scanning.
        packages("my.package");

        // Register my custom provider - not needed if it's in my.package.
        register(SecurityRequestFilter.class);
        // Register an instance of LoggingFilter.
        register(new LoggingFilter(LOGGER, true));

        // Enable Tracing support.
        property(ServerProperties.TRACING, "ALL");
    }
}
http://stackoverflow.com/questions/18268827/how-do-i-get-jersey-2-2-jax-rs-to-generate-log-output-including-json-request
// Enable LoggingFilter & output entity.     
registerInstances(new LoggingFilter(Logger.getLogger(MyApplication.class.getName()), true));

<servlet>
    <servlet-name>my.package.MyApplication</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>

    <!-- Register JAX-RS Application, if needed. -->
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>my.package.MyApplication</param-value>
    </init-param>

    <!-- Register resources and providers under my.package. -->
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>my.package</param-value>
    </init-param>

    <!-- Register my custom provider (not needed if it's in my.package) AND LoggingFilter. -->
    <init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
        <param-value>my.package.SecurityRequestFilter;org.glassfish.jersey.filter.LoggingFilter</param-value>
    </init-param>

    <!-- Enable Tracing support. -->
    <init-param>
        <param-name>jersey.config.server.tracing</param-name>
        <param-value>ALL</param-value>
    </init-param>

    <load-on-startup>1</load-on-startup>
</servlet>
Filters prioties:
http://stackoverflow.com/questions/26989608/jersey-2-3-setting-priority-for-containerrequestfilter

Option 1:

Use the @Priorty for your filter classes, passing in a value (e.g. @Priority(1)). The lower the number, the higher the priority (Don't need for anything special in web.xml or Application subclass)
@Priority(6000)
public class MyFilter1 ... {}

@Priority(6001)
public class MyFilter2 ... {}

Option 2:

Configure it programmatically into the application via an inject-able Configurable. Something like
@ApplicationPath("/")
public class MyApplication extends Applciation {
    public MyApplication(@Context Configurable configurable) {
        configurable.register(MyFilter1.class, 1000);
        configurable.register(MyFilter2.class, 1001);
    }
}
Or with ResourceConfig simply calling register without the injected Configurable. See the API for overloaded register
public ResourceConfig register(Object component, int bindingPriority)
e.g.
public class MyApplication extends ResourceConfig {
    public MyApplication() {
        ...
        register(TestFilter.class, 6000);
        register(TestFilter2.class, 6001);*/
    }
}

Note:

Just an FYI, there are built in constants from the Priorites class.
public final class Priorities {
    private Priorities() { }

    public static final int AUTHENTICATION = 1000;
    public static final int AUTHORIZATION = 2000;
    public static final int HEADER_DECORATOR = 3000;
    public static final int ENTITY_CODER = 4000;
    public static final int USER = 5000;
}

Jersey client:
https://jersey.java.net/documentation/latest/client.html
Client client = ClientBuilder.newClient(new ClientConfig()
        .register(MyClientResponseFilter.class)
        .register(new AnotherClientFilter());
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:9998").path("resource");
Form form = new Form();
form.param("x", "foo");
form.param("y", "bar");
MyJAXBBean bean =
target.request(MediaType.APPLICATION_JSON_TYPE)
    .post(Entity.entity(form,MediaType.APPLICATION_FORM_URLENCODED_TYPE),
        MyJAXBBean.class);

http://howtodoinjava.com/jersey/jersey-restful-client-examples/
Client client = ClientBuilder.newClient( new ClientConfig().register( LoggingFilter.class ) );
WebTarget webTarget = client.target("http://localhost:8080/JerseyDemos/rest").path("employees");
Invocation.Builder invocationBuilder =  webTarget.request(MediaType.APPLICATION_XML);
Response response = invocationBuilder.get();
Employees employees = response.readEntity(Employees.class);

Invocation.Builder invocationBuilder =  webTarget.request(MediaType.APPLICATION_XML);
Response response = invocationBuilder.post(Entity.entity(emp, MediaType.APPLICATION_XML));
System.out.println(response.getStatus());
System.out.println(response.readEntity(String.class));

http://stackoverflow.com/questions/29434312/is-it-possible-in-jersey-to-have-access-to-an-injected-httpservletrequest-inste
Or inject it as a method param. Singleton or not, you will get the actual instance
@GET
public String getType(@Context HttpServletRequest request) {
    return request.getClass().getName();
}
Issues:
https://java.net/jira/browse/JERSEY-2506
Basically, it's impossible to inject Servlet artefacts (e.g. HttpServletRequest) into Spring beans due to this usingjavax.inject.Provider or the Spring ObjectFactoryDelegatingInvocationHandler proxy.




Issues:
jersey-spring3 doesn't support Spring Java config properly
https://java.net/jira/browse/JERSEY-2038

The new jersey-spring3 module expects an XML based spring configuration
I found a workaround that worked for my situation (I only want to use Spring for IoC). I couldn't find a way to do this in the Jersey ResourceConfig, and I ended up needing an extra WebApplicationInitializer.
The @Priority is there to make sure it runs before the jersey-spring3 SpringWebApplicationInitializer.
@Priority(value = 1)
public class MySpringWebInitializer implements WebApplicationInitializer
{
    @Override
    public void onStartup(ServletContext container)
    {
        //Tell jersey-spring3 the context is already initialized
        container.setInitParameter("contextConfigLocation", "NOTNULL");
        AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
        appContext.register(MySpringConfig.class);
        container.addListener(new ContextLoaderListener(appContext));
    }
}
If you are using spring boot with jersey and plan to deploy the resulting WAR on a JBoss container, this issue will probably randomly bite you during startup. If the org.glassfish.jersey.server.spring.SpringWebApplicationInitializer is detected on the classpath first and runs before org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration initializer, you will most likely end up with a duplicate context exception. In a spring boot app that already extends the SpringBootServletInitializer, all you need is this:
@Priority(value = 1)
public class MySpringWebInitializer implements WebApplicationInitializer
{
    @Override
    public void onStartup(ServletContext container)
    {
        //Tell jersey-spring3 the context is already initialized
        container.setInitParameter("contextConfigLocation", "NOTNULL");
    }
}

public class SpringWebApplicationInitializer implements WebApplicationInitializer {
    private static final String PAR_NAME_CTX_CONFIG_LOCATION = "contextConfigLocation";

    @Override
    public void onStartup(ServletContext sc) throws ServletException {
        if (sc.getInitParameter(PAR_NAME_CTX_CONFIG_LOCATION) == null) {
            LOGGER.config(LocalizationMessages.REGISTERING_CTX_LOADER_LISTENER());
            sc.setInitParameter(PAR_NAME_CTX_CONFIG_LOCATION, "classpath:applicationContext.xml");
            sc.addListener("org.springframework.web.context.ContextLoaderListener");
            sc.addListener("org.springframework.web.context.request.RequestContextListener");
        } else {
            LOGGER.config(LocalizationMessages.SKIPPING_CTX_LODAER_LISTENER_REGISTRATION());
        }
    }

}
How to make Jersey to use SLF4J instead of JUL?
http://stackoverflow.com/questions/33746425/pure-jerseytest-without-letting-spring-messing-with-services
http://stackoverflow.com/questions/4121722/how-to-make-jersey-to-use-slf4j-instead-of-jul
If you are using the client API you can manually redirect the logs to slf4j (note that it may break in future versions although it seems unlikely):
Logger LOG = LoggerFactory.getLogger(MyClass.class); //slf4j logger

WebTarget ws = ClientBuilder.newClient(config)
                  .register(new LoggingFilter(new JulFacade(), true));

private static class JulFacade extends java.util.logging.Logger {
  JulFacade() { super("Jersey", null); }
  @Override public void info(String msg) { LOG.info(msg); }
}
The best way to do it is through a custom Listener. Being initialized before JSF servlet it should configure jul-to-slf4j bridge in contextInitialized(ServletContextEvent).
I try to use SLF4JBridgeHandler to bridge JUL to SLF4J and I've got a lot of uninteresting log in my log file
I need to filter but it seems to work fine

PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(maxTotal);
connectionManager.setDefaultMaxPerRoute(maxPerRoute());

ClientConfig clientConfig = new ClientConfig();
clientConfig.property(ClientProperties.READ_TIMEOUT, readTimeout);
clientConfig.property(ClientProperties.CONNECT_TIMEOUT, connectionTimeout);
clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);
clientConfig.property(ClientProperties.FOLLOW_REDIRECTS, false);
clientConfig.property(ClientProperties.PROXY_URI, proxy);

ApacheConnectorProvider connector = new ApacheConnectorProvider();
clientConfig.connectorProvider(connector);
JacksonJaxbJsonProvider jacksonProvider = new JacksonJaxbJsonProvider();
jacksonProvider.setMapper(new ObjectMapper());
clientConfig.register(jacksonProvider);
clientConfig.property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, suppressHttpValidation);
http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/
Spring Annotation Style Best Practices
  1. Explicitly name your component [@Component(“beanName”)]
  2. Use ‘@Resource’ with the ‘name’ attribute [@Resource(name=”beanName”)]
  3. Avoid ‘@Qualifier’ annotations unless you want to create a list of similar beans. For example you may want to mark a set of rules with a specific ‘@Qualifier’ annotation. This approach makes it simple to inject a group of rule classes into a list that can be used for processing data.
  4. Scan specific packages for components [context:component-scan base-package=”com.sourceallies.person”]. While this will result in more component-scan configurations it reduces the chance that you’ll add unnecessary components to your Spring context.
RESTful Java Web Services - Second Edition

Reporting errors using ResponseBuilder

Reporting errors using WebApplicationException

Some of the exceptions extended from WebApplicationException are as follows: BadRequestException, ForbiddenException, NotAcceptableException, NotAllowedException, NotAuthorizedException, NotFoundException, NotSupportedException, RedirectionException, InternalServerErrorException, and ServiceUnavailableException



in the request processing cycle, the default exception mapper class deployed by the JAX-RS runtime will intercept the exception thrown by the method and will generate an appropriate HTTP response object. WebApplicationException can be created by wrapping the response content, error text, or HTTP status code. 



@NotNull

@Null

@AssertTrue

@AssertFalse

@DecimalMax

@DecimalMin

@Digits



@Max

@Min



@Future
The annotated variable must be a date in the future.
@Past
@Pattern
@Size

MARSHALLING CSV REPRESENTATION TO JAVA OBJECTS WITH MESSAGEBODYREADER
MARSHALLING JAVA OBJECTS TO THE CSV REPRESENTATION WITH MESSAGEBODYWRITER
public void findAllDepartments(@Suspended final 
    AsyncResponse asyncResponse) {
    //Set time out for the request
    asyncResponse.setTimeout(10, TimeUnit.SECONDS);
    Runnable longRunningDeptQuery = new Runnable(){
        EntityManagerFactory emf = 
            Persistence.
                createEntityManagerFactory("HRPersistenceUnit");
        EntityManager entityManagerLocal = emf.createEntityManager();

        public void run() {
            CriteriaQuery cq = 
                entityManagerLocal.
                    getCriteriaBuilder().createQuery();
            cq.select(cq.from(Department.class));
            List<Department> depts = 
                entityManagerLocal.createQuery(cq).getResultList();
            GenericEntity<List<Department>> entity
                = new GenericEntity<List<Department>>(depts) {
            };
            asyncResponse.
                resume(Response.ok().entity(entity).build());
        }
    };
    executorService.execute(longRunningDeptQuery);
}

WebTarget webTarget = 
    client.target(BASE_URI).path("hr").path("departments");
AsyncInvoker asyncInvoker = webTarget.
    request(javax.ws.rs.core.MediaType.APPLICATION_JSON).async();
Future<List<Department>> entity = asyncInvoker.get(
    new InvocationCallback<List<Department>>() {
    @Override
    public void completed(List<Department> response) {
        //Call back on request completion
        //You can process the result here, if required
        client.close();
    }

    @Override
    public void failed(Throwable throwable) {
        //Call back on request failure
        //Handle the exception
        //log(...) method definition is not shown here
        log(throwable);
    }
});

@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext requestContext,
        ContainerResponseContext cres) throws IOException {
       //Specify CORS headers: * represents allow all values
        cres.getHeaders().add("Access-Control-Allow-Origin", "*");
        cres.getHeaders().add("Access-Control-Allow-Headers", 
            "*");
        cres.getHeaders().add("Access-Control-Allow-Credentials", 
            "true");
        cres.getHeaders().add("Access-Control-Allow-Methods", 
            "GET, POST, PUT, DELETE, OPTIONS, HEAD");
        cres.getHeaders().add("Access-Control-Max-Age", 
            "1209600");
    }
}

You use the javax.ws.rs.ext.ReaderInterceptor interface to intercept and manipulate the incoming message body.

While processing a request, the request filter with the least priority will be executed first and followed by the next one in the sequence. While processing a response, filters are executed in the reverse order.

Selectively applying filters and interceptors on REST resources by using @NameBinding
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface RequestLogger {
}
@RequestLogger 
public class RequestLoggerFilter implements ContainerRequestFilter {
    @Override
    public void filter(ContainerRequestContext requestContext) 
        throws IOException {
    //Method implementation is not shown in this
    //example for brevity
    }
}

The javax.ws.rs.container.DynamicFeature contract is used by the JAX-RS runtime to register providers, such as interceptors and filters, to a particular resource class or method during application deployment.

<plugin>
    <groupId>org.raml.plugins</groupId>
    <artifactId>jaxrs-raml-maven-plugin</artifactId>
    <!-- Specify the appropriate version -->
    <version>1.3.3</version>
    <configuration>
        <sourceDirectory>
             ${basedir}/src/main/java
        </sourceDirectory>
        <baseUrl>
            http://localhost:8080/hrapp/webresources
        </baseUrl>
        <title>Department Resource</title>
        <outputFile>
            ${project.build.directory}/generated-sources/dept-api.raml
        </outputFile>
        <removeOldOutput>true</removeOldOutput>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>generate-raml</goal>
            </goals>
            <phase>process-classes</phase>
        </execution>
    </executions>
</plugin>
Including the version in a HTTP Accept header – the media type versioning
The media type versioning approach adds the version information to the media content type. You can do this by introducing custom vendor media types that hold the version information along with the media type details.
Accept: application/vnd.{app_name}.{version}+{response_type}
@Stateless
@Api(value = "/departments", description = "Get departments details")
    @ApiOperation(value = "Find department by id",
        notes = "Specify a valid department id",
        response = Department.class)
    @ApiResponses(value = {
        @ApiResponse(code = 200, message = "successful operation"),
        @ApiResponse(code = 404, message = "Department not found")
    })
    @ApiParam(value = "The department id", required = true) 

    @Produces({"application/json", "application/vnd.packtpub.v1+json"})
    @Consumes({"application/json", "application/vnd.packtpub.v1+json"})
    public class DepartmentResource{
        //The following method is a modified implementation
        //to read the list of employees, so the version number has been
        //incremented
        @GET
        @Produces({"application/vnd.packtpub.v2+json"})
        public List<Department> findDepartmentsInRangeV2(
            @QueryParam("offset") @DefaultValue("1") Integer offset, 
            @QueryParam("limit") @DefaultValue("20") Integer limit) {
            return findDepartmentEntitiesWithDetails(offset, limit);
        }
The REST API client can specify an X-HTTP-Method-Override request header with a string value containing either PUT, PATCH, or DELETE. When the server gets the request, the server replaces the POST method call with the method string value set for X-HTTP-Method-Override.

JAX-RS allows you to implement this behavior via prematching javax.ws.rs.container.ContainerRequestFilter.
@PreMatching
// A provider impl for handling the X-Http-Method-Override header 
public class HttpOverride implements ContainerRequestFilter {

    public void filter(ContainerRequestContext ctx) {
        String method = ctx.getHeaderString
            ("X-Http-Method-Override");
        //override header should only be accepted on POST
        if (method != null 
            && ctx.getMethod().equals("POST"))
        //Set the method to the X-HTTP-Method-Override header value
            ctx.setMethod(method);
    }
}

You can use PUT for creating or updating a resource when the client has the full resource content available. In this case, all values are with the client, and the server does not generate a value for any of the fields.

You will use POST for creating or updating a resource if the client has only partial resource content available. Note that you are losing the idempotency support with POST. An idempotent method means that you can call the same API multiple times without changing the state. This is not true for the POST method; each POST method call may result in a server state change. PUT is idempotent, and POST is not

Implementing partial response
/employees/1234?select=firstName,lastName,email
SelectableEntityFilteringFeature
https://github.com/jersey/jersey/tree/2.18/examples/entity-filtering-selectable

register(SelectableEntityFilteringFeature.class);
property(SelectableEntityFilteringFeature.QUERY_PARAM_NAME, "select");
// Configure MOXy Json provider. Comment this line to use Jackson. Uncomment to use MOXy.
register(new MoxyJsonConfig().setFormattedOutput(true).resolver());

final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI,
        new SelectableEntityFilteringApplication());

        UriBuilder builder = uriInfo.getAbsolutePathBuilder();
        builder.path(deptId.toString());
        return Response.created(builder.build()).build();

http://stackoverflow.com/questions/38133680/why-do-we-need-component-spring-annotation-for-jersey-resource-in-spring-boot-s
You don't need it. Jersey uses HK2 as it's internal DI framework, and HK2 has a Spring bridge. This is what's used internally to bridge Spring components into the HK2 IoC container, so that they can be injected into Jersey components. And Jersey implements an AutowiredInjectionResolver1 that allows for injection of Spring components using @Autowired. You don't even need @Autowiredthough. All the Spring components can be injected with the normal @Inject.
The only drawback I've ran into, not making the Jersey components a Spring @Component is that it doesn't support @Value when you want to inject property values.
The one thing I don't like is that when you declare something a Spring @Component, it automatically makes it a singleton. But Jersey resources are by default request scoped. You can add a Spring @Scope("request"), and it should change the resource to a request scoped resource. Jersey hasdeclared the Spring RequestScope, so we can use it. How exactly it ties in to Jersey's request scope, I am not a hundred percent sure. I ran into a problem a while back. I can't remember what it was, but that has kept me from ever using the Spring request scope again.
Assuming I want to keep all my resources request scoped, I would take sticking to the normal Jersey request scope, and not being able to inject @Values, over having to use Spring's request scope. Maybe I'm imagining things, and there was no issue using it, but personally I'll just stick to what I know works :-)

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts