REST 请求处理

一.Providers 详解

javax.ws.rs.ext.Providers 是JAX-RS 2.0定义的一种辅助接口,其实现类用于辅助REST框架完成过滤和读写拦截的功能,可以使用@Provider 注解标注这些类。Providers接口一共定义了四个方法,分别用来获取MessageBodyReader,MessageBodyWriter,ExceptionMapper,ContextResolver


package javax.ws.rs.ext;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.core.MediaType;

public interface Providers {

   
     MessageBodyReader getMessageBodyReader(Class type,
                                                  Type genericType, Annotation[] annotations, MediaType mediaType);

     MessageBodyWriter getMessageBodyWriter(Class type,
                                                  Type genericType, Annotation[] annotations, MediaType mediaType);
 
     ExceptionMapper getExceptionMapper(Class type);

  
     ContextResolver getContextResolver(Class contextType,
                                              MediaType mediaType);
}

1.实体Providers

Jersey 之所以支持那么多中响应实体的传输格式,是因为其底层实体Providers具备的对不同格式的处理能力。Jersey内部提供了丰富的MessageBodyReader和MessageBodyWriter 接口的实现类,用于处理不同格式的表述

REST 请求处理_第1张图片
MessageBodyReader实现类
REST 请求处理_第2张图片
MessageBodyWriter 实现类

二.REST请求流程

REST 请求处理_第3张图片
REST请求流程

如上图,请求流程中存在三种角色,分别是:用户,REST客户端和REST服务器,请求始于请求的发送,止于调用Resonse的readEntity()方法
(1).用户请求提交数据,客户端接收请求,进入第一个扩展点:客户端请求过滤器 ClientRequestFilter 的filter()方法
(2).请求处理过滤完毕后,流程进入第二个扩展点:客户端写拦截器WriterInterceptor实现类的aroundWriterTo() 方法,实现对客户端序列化操作的拦截
(3).客户端消息体写处理器MessageBodyWriter 执行序列化,流程从客户端过渡到服务器端
(4).服务器接收请求,流程进入第三个扩展点:服务器前置请求过滤器ContainerRequestFilter实现类 的filter()方法
(5).过滤器处理完毕后,服务器根据请求匹配资源方法,如果匹配到相应的资源方法,流程进入第四个扩展点:服务器后置请求过滤器ContainerRequestFilter 实现类 的filter() 方法
(6).后置请求过滤器处理完毕后,力促进入第五个扩展点:服务器读拦截器ReaderInterceptor实现类 的aroundReadFrom() 方法,拦截服务器端反序列化操作
(7).服务器消息体读处理器MessageBodyReader 完成对客户端数据流的反序列化,服务器执行匹配的资源方法
(8).REST请求资源的处理完毕后,流程进入第六个扩展点:服务器响应过滤器 ContainerResponseFilter 实现类 的filter() 方法
(9).过滤器处理完毕后,流程进入第七个扩展点:服务器写拦截器WriterInterceptor实现类 的aroundWriterTo() 方法,实现对服务器端序列化到客户端这个操作的拦截
(10).服务器消息体写处理器MessageBodyWriter 执行序列化,流程返回到客户端一侧
(11).客户端接收响应,流程进入第八个扩展点:客户端响应过滤器ClientResponseFilter 实现类 的filter() 方法
(12).过滤处理完毕后,客户端响应实例response 返回到用户一侧,用户执行response.readEntity(),流程进入第九个扩展点:客户端拦截器ReaderInterceptor实现类 的aroundReadFrom() 方法,对客户端反序列化进行拦截
(13).客服端消息体读处理器MessageBodyReader 执行反序列化,将Java类型的对象最终作为readENtity()方法的返回值

三.REST过滤器

JAX-RS-2.0定义的4种过滤器扩展点接口,供开发者实现其业务逻辑,按请求处理流程的先后顺序为:客户端请求过滤器(ClientRequestFilter) -------> 服务端请求过滤器(ContainerRequestFilter)-------->服务端响应过滤器(ContainerResponseFilter)——>客户端响应过滤器(ClientResponseFilter)

ClientRequestFilter

@Produces
public class AirClientRequestFilter implements ClientRequestFilter {

    private static final Logger LOGGER = Logger.getLogger(AirClientRequestFilter.class);

    @Override
    public void filter(final ClientRequestContext requestContext) throws IOException {
        AirClientRequestFilter.LOGGER.info("AirClientRequestFilter invok " + requestContext.getUri());
    }
}

ClientResponseFilter

@Produces
public class AirClientResponseFilter implements ClientResponseFilter {

    @Override
    public void filter(final ClientRequestContext requestContext, final ClientResponseContext responseContext) throws IOException {

    }
}

ContainerRequestFilter

@PreMatching
@Provider
public class AirContainerRequestPreFilter implements ContainerRequestFilter {
    private static final Logger LOGGER = Logger.getLogger(AirContainerRequestPreFilter.class);

    public AirContainerRequestPreFilter() {
        LOGGER.info("Air-Container-Request-Pre-Filter initialized");
    }
    @Override
    public void filter(final ContainerRequestContext requestContext) throws IOException {
        AirContainerRequestPreFilter.LOGGER.info("Air-Container-Request-Pre-Filter invoked");
    }
}

ContainerResponseFilter

@Provider
public class AirContainerResponseFilter implements ContainerResponseFilter {
    private static final Logger LOGGER = Logger.getLogger(AirContainerResponseFilter.class);

    public AirContainerResponseFilter() {
        LOGGER.info("Air-Container-Response-Filter initialized");
    }
    
    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        LOGGER.info("Air-Container-Response-Filter invoked");
    }
}

四.REST拦截器

Jersey 内部实现了几个典型应用的拦截器,他们是成对出现的
ReaderInterceptor

@Provider
public class AirReaderInterceptor implements ReaderInterceptor {
    private static final Logger LOGGER = Logger.getLogger(AirReaderInterceptor.class);

    public AirReaderInterceptor() {
        LOGGER.info("AirReaderInterceptor initialized");
    }
    
    @Override
    public Object aroundReadFrom(final ReaderInterceptorContext context) throws IOException, WebApplicationException {
        return null;
    }
}

WriterInterceptor

@Provider
public class AirWriterInterceptor implements WriterInterceptor {
    private static final Logger LOGGER = Logger.getLogger(AirWriterInterceptor.class);

    public AirWriterInterceptor() {
        LOGGER.info("AirWriterInterceptor initialized");
    }
    @Override
    public void aroundWriteTo(final WriterInterceptorContext context) throws IOException, WebApplicationException {
    }
}

编码解码拦截器(ContentEncoder)

public class AirEncoderInterceptor extends ContentEncoder {
    @Override
    public InputStream decode(String s, InputStream inputStream) throws IOException {
        return null;
    }

    @Override
    public OutputStream encode(String s, OutputStream outputStream) throws IOException {
        return null;
    }
}

五.优先级

优先级的定义使用注解@Priority,优先级的值是一个整数值,对于ContainerReauest,PreMatchContainerRequest,ClientRequest 和读写拦截器 采用升序策略,数值越小,优先级越高;对于ContainerResponse和ClientResponse采用降序策略,数值越大,优先级越高

你可能感兴趣的:(REST 请求处理)