Servlet 过滤器和 Jersey 过滤器有啥区别?

Posted

技术标签:

【中文标题】Servlet 过滤器和 Jersey 过滤器有啥区别?【英文标题】:What is the difference between a Servlet filter and a Jersey filter?Servlet 过滤器和 Jersey 过滤器有什么区别? 【发布时间】:2019-02-11 21:04:07 【问题描述】:

我阅读了很多教程,但我不明白 Servlet 过滤器和 Jersey 过滤器之间的区别。谁能给我解释一下这些区别?

【问题讨论】:

【参考方案1】:

在 Servlet 容器中,有 Servlet 和 Servlet 过滤器。通常,Servlet 处理请求,而 Servlet Filter 处理请求的 pre an post 处理。所以请求流看起来像

Request --> Filter --> Servlet --> Filter --> Response

Jersey 应用程序实现为 Servlet1。因此,在上述流程中,只需将“Servlet”替换为 Jersey。

Request --> Filter --> Jersey-Servlet --> Filter --> Response

Jersey 也有自己的过滤器,即ContainerRequestFilterContainerResponseFilter。它们的用途与 Servlet 过滤器相同,只是在 Jersey 应用程序的上下文中;它们用于预处理和后处理。以下流程在 Jersey 请求中。

Req --> ContainerRequestFilter --> Resource --> ContainerResponseFilter --> Res

因此,这些过滤器具有相同的用途,即对请求进行预处理和后处理。主要区别在于它们连接的级别。 Servlet 过滤器绑定在 servlet 级别,而 Jersey 过滤器绑定在 Jersey 级别。

那么你应该使用哪一个?

这取决于您希望何时调用它以及您需要访问哪些信息。以安全为例。在考虑保护您的应用程序时,您可能希望您的安全门尽可能远离数据。因此,您可以使用 Servlet 过滤器来实现您的安全性。但是您需要的信息只能在 Jersey 应用程序中获得。然后你需要使用 Jersey 过滤器;例如,您需要知道调用了哪个资源方法。您只能从 Jersey 过滤器中的 ResourceInfo 获取此信息

class MyResource 
    @RolesAllowed("ADMIN")
    public Response get() 


class AuthorizationFilter implements ContainerRequestFilter 
    @Context
    private ResourceInfo resourceInfo;

    @Override
    public void filter(ContainerRequestContext request) 
        Method method = resourceInfo.getResourceMethod();
        RolesAllowed rolesAllowed = method.getAnnotation(RolesAllowed.class);
    

您无法在 Servlet 过滤器中执行上述操作。此信息只能从 Jersey 应用程序的上下文中访问。也许您可能想在 Servlet 过滤器中处理 身份验证,并在身份验证后将结果存储在 HttpServletRequest 属性中。然后在 authorization 中,您可以在 Jersey 级别处理它,如上所示。您可以将 HttpServletRequest 注入 Jersey 过滤器,并从那里获取属性。

这只是一个例子。有很多用例。您只需要确定最适合您的应用程序的过滤器类型即可。大多数情况下,您可以使用 Jersey 过滤器,但有时您需要在请求中尽早调用过滤器,在这种情况下,您可能需要使用 Servlet 过滤器。在其他情况下,您需要访问只能在 Jersey 应用程序中获得的信息。为此,您应该使用 Jersey 过滤器。


脚注

1。 Jersey 应用程序也可以配置为作为 Servlet 过滤器而不是 Servlet 运行。我相信他们之所以提供此选项,是因为某些 Jersey 功能需要一些仅存在于过滤器中的功能。

【讨论】:

是否总是在 Jersey 过滤器之前调用 Servlet 过滤器?我有一个像你上面提到的用例,其中有用于身份验证的 Servlet 过滤器。过滤器将用户主体存储在 HttpServletRequest 中。然后我有一个 Jersey 过滤器来从 HttpServletRequest 中提取用户主体,但无法找到它。有什么方法可以检查过滤器被调用的顺序。 Servlet 过滤器来自一个库,所以我无法在那里更改任何内容。 您需要告诉过滤器应该调用哪些路径。能告诉你的就这些了。如果配置正确,应该在 Jersey 之前调用它。 我在泽西岛Feature 班级注册他们。但是从日志中,我可以推断出它们没有被调用。我应该在web.xml 中注册它们吗? 是的,您需要在 web.xml 中而不是在 Jersey 中配置它们,Servlet 过滤器位于 Jersey 应用程序之外。

以上是关于Servlet 过滤器和 Jersey 过滤器有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 Spring Boot 中将 Jersey 用作 servlet 和过滤器吗?

Jersey 的 servlet 或过滤器

什么是泽西过滤器?

你能用 JAX-RS/Jersey 做传统的 Servlet 过滤吗?

让 Spring 了解 Jersey 过滤器

Servlet 过滤器和 Servlet 上下文侦听器有啥区别?