Java 在 Jersey 生命周期中如何拦截请求?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4358213/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 16:27:01  来源:igfitidea点击:

How does one intercept a request during the Jersey lifecycle?

javaapijax-wsjerseyjax-rs

提问by cww

I've used Jersey for the better part of a year now and have just stumbled upon a problem to which I can't find the answer: how do you intercept (or hook into) the Jersey request lifecycle?

我已经使用 Jersey 一年的大部分时间了,只是偶然发现了一个我找不到答案的问题:您如何拦截(或挂钩)Jersey 请求生命周期?

Ideally, I'd be able to perform some custom filtering/validation/rejection between the time the container accepts the request from the network and the time my handler methods are called. Bonus points if there's an easy way to filter the interceptors by sub-path (e.g. have one interceptor for anything under /, another for anything under /user/, etc.).

理想情况下,我能够在容器接受来自网络的请求和调用我的处理程序方法之间执行一些自定义过滤/验证/拒绝。如果有一种简单的方法可以通过子路径过滤拦截器(例如,有一个拦截器用于 / 下的任何内容,另一个用于 /user/ 下的任何内容,等等),则加分。

Thanks!

谢谢!

Edit: To be a bit clearer, the general idea here is to be able to write some code that will be run for many API calls without having to explicitly call that code from each handler method. This would reduce extra code and eliminate the need to pass request contexts around.

编辑:更清楚一点,这里的一般想法是能够编写一些代码,这些代码将在许多 API 调用中运行,而无需从每个处理程序方法中显式调用该代码。这将减少额外的代码并消除传递请求上下文的需要。

采纳答案by cww

I've found the answer.

我找到了答案。

First, create a class that implements ContainerRequestFilter. The interface specifies the following method, in which the filtering takes place. The ContainerRequest object contains information about the current request.

首先,创建一个实现ContainerRequestFilter 的类。该接口指定了以下方法,在该方法中进行过滤。ContainerRequest 对象包含有关当前请求的信息。

public ContainerRequest filter(ContainerRequest req);

After that, include the following XML in the servlet configuration in web.xml

之后,在 web.xml 中的 servlet 配置中包含以下 XML

<init-param>
  <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
  <param-value>path.to.filtering.class</param-value>
</init-param>

Sources:

资料来源:

http://jersey.576304.n2.nabble.com/ContainerRequestFilter-and-Resources-td4419975.htmlhttp://markmail.org/message/p7yxygz4wpakqno5

http://jersey.576304.n2.nabble.com/ContainerRequestFilter-and-Resources-td4419975.html http://markmail.org/message/p7yxygz4wpakqno5

回答by a1o1

Have you looked at the Jersey ClientFilterclass ?

你看过泽西ClientFilter课吗?

We are currently using this to intercept and perform API versioing etc.. There is built in logging filters - so you can look at the code for them to get an idea of what to write.

我们目前正在使用它来拦截和执行 API 版本等。有内置的日志过滤器 - 因此您可以查看它们的代码以了解要编写的内容。

The signature is:

签名是:

public ClientResponse handle(final ClientRequest cr) throws ClientHandlerException...

So you can start by doing stuff like:

所以你可以从做这样的事情开始:

....
cr.getHeaders()
....
return getNext().handle(cr);

回答by a1o1

For the server part we use a Jersey Specific class to do something like this: ContainerResponseFilter

对于服务器部分,我们使用 Jersey 特定类来执行以下操作: ContainerResponseFilter

The signature is:

签名是:

public ContainerResponse filter(ContainerRequest request, ContainerResponse response)

then you can do calls like:

然后你可以做这样的电话:

Object entity  = response.getEntity();
    ... your logic here ...
return response;

Can this be of some help ?..

这可以有一些帮助吗?..

回答by markthegrea

This thread is a bit old, but I was having a fit of a time intercepting both before and afterthe request. After a long search on the web, I finally figured this out:

这个线程有点旧,但我在请求之前和之后都有一段时间拦截。在网上找了很久,终于弄明白了:

<init-param>
    <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
    <param-value>blah.LoggingFilter</param-value>
</init-param>
<init-param>
    <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
    <param-value>blah.LoggingFilter</param-value>
</init-param>

and then this class:

然后这个类:

public class LoggingFilter extends LoggingFilter implements ContainerRequestFilter {

    private static final ThreadLocal<Long> startTime = new ThreadLocal<Long>();
    public static boolean verboseLogging = false;

    @Override
    public ContainerRequest filter(ContainerRequest arg0) {
        startTime.set(System.currentTimeMillis());
        return arg0;
    }

    @Override
    public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
        System.out.println(System.currentTimeMillis() - startTime.get().longValue());
        StringBuilder sb = new StringBuilder();
        sb.append("User:").append((request.getUserPrincipal() == null ? "unknown" : request.getUserPrincipal().getName()));
        sb.append(" - Path:").append(request.getRequestUri().getPath());
        //...
    }

This intercepts the request at the beginning and the end so you can put in a timer or whatever.

这会在开始和结束时拦截请求,因此您可以放入计时器或其他任何内容。

This works for Jersey 1.17. Not sure about 2.x.

这适用于泽西岛 1.17。不确定 2.x。