问题描述
我有一个JAX-RS Web服务,它返回一个take JSON请求参数(映射到Parameter对象),如下所示(它在WebLogic 12.2.1中运行).是否可以编写一个拦截器或过滤器,以便在调用Web服务时,它将在JSON请求消息中添加一个额外的字段,以便下面的方法将在requestParameters中获得该额外的字段?
I have a JAX-RS web service that returns a takes JSON request parameters (which map to Parameter object) as shown below (it is running in WebLogic 12.2.1). Is it possible to write an interceptor or filter, such that when the web service is called, it will add an extra field in the JSON request message, so that the below method will get that extra field in the requestParameters?
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("LogIn")
public Response logIn(@Context HttpServletRequest request, Parameters requestParameters) {...}
谢谢!
推荐答案
拦截器
这可以通过拦截器来实现.
拦截器旨在通过操纵实体输入/输出流来操纵实体.拦截器有两种, ReaderInterceptor
和 WriterInterceptor
.
Interceptors are intended to manipulate entities, via manipulating entity input/output streams. There are two kinds of interceptors, ReaderInterceptor
and WriterInterceptor
.
阅读器拦截器用于操纵入站实体流.这些是来自电线"的流.因此,使用阅读器拦截器,您可以在服务器端操纵请求实体流. Writer拦截器用于将实体写入服务器上表示写响应实体的线路"上的情况
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. Writer interceptors are used for cases where entity is written to the "wire" which on the server means when writing out a response entity
以下拦截器,实现了 ReaderInterceptor
界面,允许您在服务器端修改请求的实体:
The following interceptor, which implements the ReaderInterceptor
interface, allows you to modify the requested entity on server side:
@Provider
public class CustomReaderInterceptor implements ReaderInterceptor {
@Override
public Object aroundReadFrom(ReaderInterceptorContext context)
throws IOException, WebApplicationException {
InputStream stream = context.getInputStream();
// Manipulate the HTTP entity using the InputStream
context.setInputStream(stream);
return context.proceed();
}
}
请注意,上面的拦截器是 global ,也就是说,它将对所有资源方法都执行.
Please note the above interceptor is global, that is, it will be executed for all resource methods.
使用 Jackson 时,您的 ReaderInterceptor#aroundReadFrom(ReaderInterceptorContext)
方法的实现可能类似于:
When using Jackson, your ReaderInterceptor#aroundReadFrom(ReaderInterceptorContext)
method implementation could be like:
// Create a Jackson ObjectMapper instance (it can be injected instead)
ObjectMapper mapper = new ObjectMapper();
// Parse the requested entity into a JSON tree
JsonNode tree = mapper.readTree(context.getInputStream());
// Add a property to the JSON
((ObjectNode) tree).put("field", "value");
// Set the input stream containing the manipulated JSON
context.setInputStream(new ByteArrayInputStream(mapper.writeValueAsBytes(tree)));
// Proceed to the next interceptor in the chain
context.proceed();
名称绑定
要仅对某些精选资源方法执行拦截器,可以使用名称绑定.
名称绑定是一个概念,允许对JAX-RS运行时说,将仅对特定资源方法执行特定过滤器或拦截器.当过滤器或拦截器仅限于特定的资源方法时,我们说它是 name-bound .
Name binding is a concept that allows to say to a JAX-RS runtime that a specific filter or interceptor will be executed only for a specific resource method. When a filter or an interceptor is limited only to a specific resource method we say that it is name-bound.
可以使用将过滤器分配给资源方法@NameBinding
注释.该批注用作其他用户实施的批注的元批注,这些批注已应用于提供程序和资源方法.
Filters can be assigned to a resource method using the @NameBinding
annotation. The annotation is used as meta annotation for other user implemented annotations that are applied to a providers and resource methods.
名称绑定批注可以定义如下(批注的名称由您决定):
A name binding annotation can be defined as following (the name of the annotation is up to you):
@NameBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface CustomizeResponse { }
将上面定义的注释放在您的拦截器类上
Place the above defined annotation on your interceptor class:
@Provider
@CustomizeResponse
public class CustomReaderInterceptor implements ReaderInterceptor {
...
}
要将拦截器分配给资源方法,请将上面定义的注释放在资源方法上:
To assign the interceptor to a resource method, place the above defined annotation on the resource method:
@GET
@CustomizeResponse
@Produces(MediaType.APPLICATION_JSON)
public Response myMethod() {
...
}
名称绑定也可以应用于资源类.这意味着将对该资源类的所有资源方法执行拦截器:
Name binding can be applied on resource classes as well. It means the interceptor will be executed for all resource methods of that resource class:
@Path("/foo")
@CustomizeResponse
public class MyResource() {
...
}
请注意,始终会执行全局过滤器和拦截器 ,即使对于具有任何名称绑定批注的资源方法,也是如此.
Note that global filters and interceptor are always executed, so even for resource methods which have any name binding annotations.
有关拦截器的更多详细信息,请查看Jersey 文档 a>.
For more details on interceptors, have a look at Jersey documentation.
这篇关于拦截JAX-RS Web服务请求以添加JSON字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!