REST 请求处理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了REST 请求处理相关的知识,希望对你有一定的参考价值。

参考技术A

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

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

如上图,请求流程中存在三种角色,分别是:用户,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()方法的返回值

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

ClientRequestFilter

ClientResponseFilter

ContainerRequestFilter

ContainerResponseFilter

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

WriterInterceptor

编码解码拦截器(ContentEncoder)

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

Java Rest Assured过度处理我的get请求

我正在尝试连接到REST API(不是我自己的,所以我无法解决他们的问题)但是当我发送GET请求时,Rest Assured正在重新处理我的URI,导致调用失败。

以下是构建请求的代码:

Call rest = new Call("https://rest.test.com"); // Custom class to simplify REST calls.

JSONObject searchCriteria = new JSONObject();
searchCriteria.put("textSearchType", "SEARCHNAME");
searchCriteria.put("textSearchString", "joe blow");

String header = "Lead Inline Quick Search";

StringBuilder resource = new StringBuilder("/api/v1/search?");
resource.append("searchCriteria=")
        .append(URLEncoder.encode(searchCriteria.toString()))
        .append("&header=")
        .append(URLEncoder.encode(header));

System.out.println("REST call: " + resource.toString());

rest.get(resource.toString(), 200); // Perform a get on the query, expect a 200 response

当我查看输出时,请求是正确的:

REST call: /api/v1/search?searchCriteria=%7B%22textSearchString%22%3A%22joe+blow%22%2C%22textSearchType%22%3A%22SEARCHNAME%22%7D&header=Lead+Inline+Quick+Search

但是,当我查看Rest Assured的调试时,它会重新处理导致调用失败的请求:

Request method: GET
Request URI: https://rest.test.com/api/v1/search?searchCriteria=%257B%2522textSearchString%2522%253A%2522joe%2Bblow%2522%252C%2522textSearchType%2522%253A%2522SEARCHNAME%2522%257D&header=Lead%2BInline%2BQuick%2BSearch

注意:

  • '{'从网络编码正确转换为'%7B'并在resource中正确显示,但Rest Assured然后进一步将所有'%'转换为'%25',使得json无效({变为%257B)。
  • 由于某种原因,标题中的“+”被转换为'%20'。虽然技术上相同,但没有理由“修复”它。

如果我在构建资源时不对值进行编码,则get调用将失败,因为它会看到空格。

IllegalArgumentException-Invalid number of path parameters. Expected 1, was 0. Undefined path parameters are: "textSearchString":"joe blow","textSearchType":"SEARCHNAME".

那么对值进行编码的正确方法是什么?或者让Rest Rest确保不要用它发送的字符串来猴子?

答案

来自@Hypino的评论让我走上正轨。

.urlEncodingEnabled(false)添加到.given()并没有改变结果(调用仍然是双重处理)。但是将.setUrlEncodingEnabled(false)添加到RequestSpecBuilder()给出了正确的结果。

private RequestSpecBuilder build = new RequestSpecBuilder().setUrlEncodingEnabled(false);

记录的呼叫和实际呼叫现在是相同的:

REST call: /api/v1/search?searchCriteria=%7B%22textSearchString%22%3A%22joe+blow%22%2C%22textSearchType%22%3A%22SEARCHNAME%22%7D&header=Lead+Inline+Quick+Search

Request method: GET
Request URI: https://rest.test.com/api/v1/search?searchCriteria=%7B%22textSearchString%22%3A%22joe+blow%22%2C%22textSearchType%22%3A%22SEARCHNAME%22%7D&header=Lead+Inline+Quick+Search

以上是关于REST 请求处理的主要内容,如果未能解决你的问题,请参考以下文章

spring rest 处理空请求体(400 Bad Request)

Java Rest Assured过度处理我的get请求

Django Rest 框架中的发布请求处理

如何在 Django Rest Framework 中处理并行请求?

为啥在建立 httpSession 后 Wildfly 服务器不能处理并发 REST 请求

使用 ExtJS 4.1 REST 代理创建“批处理”请求