Java 如何仅在特定方法中使用RESTEasy预处理器?

Java 如何仅在特定方法中使用RESTEasy预处理器?,java,rest,resteasy,interceptor,Java,Rest,Resteasy,Interceptor,我正在使用RestEasy 2.3.4.Final编写一个RESTAPI。 我知道拦截器将拦截我的所有请求,预拦截器将是第一个(在所有请求之前)被调用的。我想知道如何在调用特定方法时调用此拦截器 我试图同时使用预处理拦截器和AcceptedByMethod,但无法读取所需的参数。 例如,我只需要在调用此方法时运行拦截器: @GET @Produces("application/json;charset=UTF8") @Interceptors(MyInterceptor.class) publi

我正在使用RestEasy 2.3.4.Final编写一个RESTAPI。 我知道拦截器将拦截我的所有请求,预拦截器将是第一个(在所有请求之前)被调用的。我想知道如何在调用特定方法时调用此拦截器

我试图同时使用预处理拦截器和AcceptedByMethod,但无法读取所需的参数。 例如,我只需要在调用此方法时运行拦截器:

@GET
@Produces("application/json;charset=UTF8")
@Interceptors(MyInterceptor.class)
public List<City> listByName(@QueryParam("name") String name) {...}
@GET
@产生(“应用程序/json;字符集=UTF8”)
@拦截器(MyInterceptor.class)
公共列表listByName(@QueryParam(“name”)字符串名){…}
更具体地说,我需要在所有具有
@QueryParam(“name”)

在它的签名上,这样我就可以抓住它的名字,在一切之前做点什么

可能吗?我试图在拦截器内捕获“name”参数,但未能做到这一点


有人能帮我一下吗?

您可以使用
AcceptedByMethod
,如

创建一个类,该类同时实现
预侦听器
AcceptedByMethod
。在
accept
-方法中,您可以检查该方法是否具有带
@QueryParam(“name”)
注释的参数。如果该方法具有该注释,则从
accept
-方法返回true

preProcess
-方法中,可以从
request.getUri().getQueryParameters().getFirst(“name”)
获取查询参数

编辑:

以下是一个例子:

public class InterceptorTest  {

    @Path("/")
    public static class MyService {

        @GET
        public String listByName(@QueryParam("name") String name){
            return "not-intercepted-" + name;
        }
    }

    public static class MyInterceptor implements PreProcessInterceptor, AcceptedByMethod {

        @Override
        public boolean accept(Class declaring, Method method) {
            for (Annotation[] annotations : method.getParameterAnnotations()) {
                for (Annotation annotation : annotations) {
                    if(annotation.annotationType() == QueryParam.class){
                        QueryParam queryParam = (QueryParam) annotation;
                        return queryParam.value().equals("name");
                    }
                }
            }
            return false;
        }

        @Override
        public ServerResponse preProcess(HttpRequest request, ResourceMethod method)
                throws Failure, WebApplicationException {

            String responseText = "intercepted-" + request.getUri().getQueryParameters().getFirst("name");
            return new ServerResponse(responseText, 200, new Headers<Object>());
        }
    }

    @Test
    public void test() throws Exception {
        Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
        dispatcher.getProviderFactory().getServerPreProcessInterceptorRegistry().register(new MyInterceptor());
        dispatcher.getRegistry().addSingletonResource(new MyService());

        MockHttpRequest request = MockHttpRequest.get("/?name=xxx");
        MockHttpResponse response = new MockHttpResponse();

        dispatcher.invoke(request, response);

        assertEquals("intercepted-xxx", response.getContentAsString());
    }
}
公共类拦截器测试{
@路径(“/”)
公共静态类MyService{
@得到
公共字符串listByName(@QueryParam(“名称”)字符串名称){
返回“未拦截-”+名称;
}
}
公共静态类MyInterceptor实现预侦听器AcceptedByMethod{
@凌驾
公共布尔接受(类声明、方法){
对于(注释[]注释:方法.getParameterAnnotations()){
用于(注释:注释){
if(annotation.annotationType()==QueryParam.class){
QueryParam QueryParam=(QueryParam)注释;
返回queryParam.value().equals(“name”);
}
}
}
返回false;
}
@凌驾
公共服务器响应预处理(HttpRequest请求,ResourceMethod)
引发失败,WebApplicationException{
String responseText=“intercepted-”+request.getUri().getQueryParameters().getFirst(“名称”);
返回新的ServerResponse(responseText,200,newheaders());
}
}
@试验
public void test()引发异常{
Dispatcher=MockDispatcherFactory.createDispatcher();
dispatcher.getProviderFactory().getServerPreProcessInterceptorRegistry().register(新的MyInterceptor());
dispatcher.getRegistry().addSingletonResource(新的MyService());
MockHttpRequest请求=MockHttpRequest.get(“/?name=xxx”);
MockHttpResponse response=新的MockHttpResponse();
调用(请求、响应);
assertEquals(“截获xxx”,response.getContentAsString());
}
}

如果返回
则返回新的ServerResponse(responseText,200,newheaders())你将失去终点。如果您仍然希望消息传递到最后一点,则需要返回
null

谢谢@eiden。我以前尝试过这个,但是没有使用
@Context
。但是,当我试图从注入的上下文中检索一些数据时,它会抛出一个异常,因为我想上下文没有初始化。org.apache.catalina.core.ContainerBase.[jboss.web].[default host].[api]](MSC服务线程1-3)将上下文初始化事件发送到类org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap:org.jboss.resteasy.spi.LoggableFailure:无法找到类型为javax.servlet.http.httpservletRequest的上下文数据我不知道为什么使用@context?无论如何,我已经用一个代码exampleExcellent@eiden更新了我的答案。我几乎可以这样工作,但我没有意识到
if(annotation.annotationType()==QueryParam.class){QueryParam QueryParam=(QueryParam)annotation;return QueryParam.value().equals(“name”)
非常感谢您的帮助!我希望它能帮助更多的人。不客气!
annotation.annotationType()
是一个经典的java“gotcha”: