JAX-RS, components can access which information th

2019-06-09 19:08发布

While going through the processing of a request in JAX-RS, what I studied is that the flow of the whole process is as below;

enter image description here

I know that there are different components , which serve the purpose of pluggability, like we can have filters and can plug them to whatever resource methods we want, same is the case with interceptors(and I know that they are triggered around MessageBodyWriters and MessageBodyReaders). But I am confused about each of the component and the piece of information which each component can access while the request is passing through them,

The crux which I Learned is that:


Filters

Can modify(or should deal with ) headers only. However I have seen a method getEntityStream in the ContainerRequestContext of filter. Which stream this method is referring too?

enter image description here


Interceptors

Well the only example I had was zipping the stream into some GzipReader(or something like that) over the internet . Is it the only utilisation of the Interceptor? And I suspect that the whole request body is available in the interceptor, see the image below.

enter image description here


MessageBodyReader/Writers

They are understandable, and I guess they have the same level of request information as available to that of the Interceptors.


Question:

I have not understood that what things each component can access from the incoming request, and what should be modified in each of the components, well this question may be broad , but dedicated link pointing to solution of the queries may be helpful.

Edit:

Just tested. Filter can access the message body and can modify it, So do the interceptor. ://

标签: java rest jax-rs
2条回答
劫难
2楼-- · 2019-06-09 19:26

The Jersey documentation is a good start point to learn more about the JAX-RS API:

JAX-RS Filters

Have a look at what the documentation says about filters:

Filters can be used when you want to modify any request or response parameters like headers. For example you would like to add a response header X-Powered-By to each generated response. Instead of adding this header in each resource method you would use a response filter to add this header.

There are filters on the server side and the client side.

Server filters:

Client filters:

According to the filter, you are provided with the request/response context objects that allows you to modify the requested method, the requested URI, the headers, the response status code, etc. And you also can access a stream that allows you to manipulate the request/response payload.

While ContainerRequestContext and ContainerResponseContext are available on server, ClientRequestContext and ClientResponseContext are available on client.

JAX-RS Interceptors

Have a look at what the documentation says about interceptors:

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.

There are two kinds of interceptors, ReaderInterceptor and WriterInterceptor.

Reader interceptors are used to manipulate inbound entity streams. These are the streams coming from the "wire". So, using a reader interceptor you can manipulate request entity stream on the server side (where an entity is read from the client request) and response entity stream on the client side (where an entity is read from the server response).

Writer interceptors are used for cases where entity is written to the "wire" which on the server means when writing out a response entity and on the client side when writing request entity for a request to be sent out to the server.

Writer and reader interceptors are executed before message body readers or writers are executed and their primary intention is to wrap the entity streams that will be used in message body reader and writers.

[...]

In the interceptors, you are provided with context objects so you can access the request/response payload streams. Additonaly, you can access a mutable map that allows you to manipulate the request/response headers.

ReaderInterceptorContext and WriterInterceptorContext are available both on client and on server.

查看更多
来,给爷笑一个
3楼-- · 2019-06-09 19:28

Let me start with Filters:

FILTERS:

Filters can modify inbound and outbound requests and responses including modification of headers, entity and other request/response parameters.

Further Filters are classified as Container/Server Filters and Client Filters.

Consider Server filters: There are further two obvious types:

  • request filter
  • response filter

There two main differences between these two types(depending on what they access):

  1. Response filters implement ContainerResponseFilter interface and has two arguments:

container request(ContainerRequestContext requestContext) and

container response(ContainerResponseContext responseContext).

Now what are the things these two arguments access:

public interface ContainerRequestContext

Container request filter context. A mutable class that provides request-specific information for the filter, such as request URI, message headers, message entity or request-scoped properties. The exposed setters allow modification of the exposed request-specific information.

public interface ContainerResponseContext

Container response filter context. A mutable class that provides response-specific information for the filter, such as message headers, message entity or request-scoped properties. The exposed setters allow modification of the exposed response-specific information.

Notice that requestContext can access one additional thing: requestURI

  1. Request filters implements ContainerRequestFilter and has only one argument:

container request(ContainerRequestContext requestContext)


Coming to your question:

Which stream is referred in the method setEntityStream(arg0) and getEntityStream()?

This can be broken down as:

  • getEntityStream(): Request entity stream on the server side is where an entity is read from the client request and response entity stream on the client side is where an entity is read from the server response.
  • setEntityStream(arg0): On the server means when writing out a response entity and on the client side writing request entity for a request to be sent out to the server.**

EDIT:

  1. Filters can be used to verify certain criteria for any request. If the criteria is not met, filters can also abort the response.

Consider the following example from jersey documentation:

public class AuthorizationRequestFilter implements ContainerRequestFilter {

@Override
public void filter(ContainerRequestContext requestContext)
                throws IOException {

    final SecurityContext securityContext =
                requestContext.getSecurityContext();
    if (securityContext == null ||
                !securityContext.isUserInRole("privileged")) {

            requestContext.abortWith(Response
                .status(Response.Status.UNAUTHORIZED)
                .entity("User cannot access the resource.")
                .build());
        }
    }
}

The AuthorizationRequestFilter in the example checks whether the authenticated user is in the privileged role. When the filter method is finished the response passed as a parameter to the abortWith method is used to respond to the request. Response filters, if any are registered, will be executed and will have possibility to process the aborted response.

  1. Filters can influence which method will be matched. Pre-matching filters are request filters that are executed before the request matching is started.

    @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");
        }
      }
    }
    

The PreMatchingFilter is a simple pre-matching filter which changes all PUT HTTP methods to POST. This might be useful when you want to always handle these PUT and POST HTTP methods with the same Java code.


INTERCEPTORS:

Write-Interceptors wraps the entity into GZIPOutput stream and Reader-Interceptor wraps the entity into GZIPInput stream which decompresses the data from the compressed entity received.

IN ADDITION, Interceptors can also be used to provide Digital Signatures. For Digital Signatures, a hash of the body needs to be calculated and added to the Signature request (client-side) or response (server-side) header.

查看更多
登录 后发表回答