【问题标题】:How to use RESTEasy PreProcessInterceptor only in specific methods?如何仅在特定方法中使用 RESTEasy PreProcessInterceptor?
【发布时间】:2012-07-06 21:49:40
【问题描述】:

我正在编写一个 REST API,使用 RestEasy 2.3.4.Final。 我知道 Interceptor 将拦截我的所有请求,并且 PreProcessInterceptor 将是第一个(在所有内容之前)被调用的。我想知道如何让这个拦截器在特定方法被调用时被调用。

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

@GET
@Produces("application/json;charset=UTF8")
@Interceptors(MyInterceptor.class)
public List<City> listByName(@QueryParam("name") String name) {...}

更具体地说,我需要在所有具有@QueryParam("name") 的方法中运行我的拦截器

在它的签名上,这样我就可以在一切之前抓住名字并做一些事情。

有可能吗?我试图在拦截器中捕获“名称”参数,但我无法做到。

有人可以帮帮我吗?

【问题讨论】:

    标签: java rest resteasy interceptor


    【解决方案1】:

    您可以按照RESTEasy documentation 中的说明使用AcceptedByMethod

    创建一个实现PreProcessInterceptorAcceptedByMethod 的类。在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());
        }
    }
    

    【讨论】:

    • 谢谢@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?无论如何,我已经用代码示例更新了我的答案
    • 优秀@eiden。我几乎可以这样工作,但我没有意识到if(annotation.annotationType() == QueryParam.class){ QueryParam queryParam = (QueryParam) annotation; return queryParam.value().equals("name"); 非常感谢您的帮助!我希望它可以帮助更多的人。
    • 不客气! annotation.annotationType() 是一个经典的 java 'gotcha' :)
    【解决方案2】:

    如果您返回return new ServerResponse(responseText, 200, new Headers&lt;Object&gt;());,您将失去终点。如果您仍然希望将消息传递到最后一点,则需要返回null

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-07
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-16
      • 2019-08-11
      • 1970-01-01
      相关资源
      最近更新 更多