java - 拦截器在 Servlet 中的方法级别不起作用

标签 java wildfly cdi interceptor

我有一个简单的 Web 应用程序 Maven 项目,其结构如下:

enter image description here

SimpleServlet.java 是一个具有以下代码的 servlet:

@Logger
public class SimpleServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("hello");
    }

}

Logger类是一个拦截器接口(interface),代码如下:

@InterceptorBinding
@Retention(RUNTIME)
@Target({ METHOD, TYPE })
public @interface Logger {}

MyLogger 类是一个拦截器实现,代码如下:

@Interceptor
@Logger
public class MyLogger {

    @AroundInvoke
    public Object veQuePedo(InvocationContext ctx) throws Exception {
        System.out.println("Logged");
        return ctx.proceed();
    }

}

我的web.xml:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
          version="3.0">

  <display-name>Archetype Created Web Application</display-name>
  <servlet>
        <servlet-name>ThaServlet</servlet-name>
        <servlet-class>com.SimpleServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ThaServlet</servlet-name>
        <url-pattern>/hola</url-pattern>
    </servlet-mapping>
</web-app>

还有我的 beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                           http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
    version="1.1"
    bean-discovery-mode="all">
    <interceptors>
        <class>com.MyLogger</class>
    </interceptors>
</beans>

情况是,我读到拦截器仅适用于CDI beans,我测试并注意到这是正确的。

在本示例中,我们讨论的是 servlet,因此我向您提出以下问题:

1) 如果我的 servlet(我的示例中的那个)不被视为 CDI bean,为什么当我设置 @Logger 拦截器时会起作用?

2) 为什么我的 servlet 中的拦截器 @Logger 在方法级别不起作用,而在类级别却工作正常?

在方法级别使用注释进行调试时,我看到 servlet 已被包装,但由于某种原因,@AroundInvoke 方法被忽略。

enter image description here

最佳答案

CDI 提供的服务(如拦截)通常仅发生在业务方法调用上。

本质上,这些是通过上下文引用(注入(inject)的 bean,或者容器调用被视为 Servlet 等 bean 的组件上的方法)来调用方法。

在你的例子中,从bean“外部”到bean“内部”​​调用的方法不是 doGet() —— 它是其他一些继承的方法。对 doGet() 的调用来自 bean 本身,无法被拦截。

这就是为什么您在类级别的拦截似乎被拦截了一次,尽管它不在您稍后尝试直接注释的 doGet() 上。

关于java - 拦截器在 Servlet 中的方法级别不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44930897/

相关文章:

java - Hibernate 一对多映射

JAVA 和 PHP 在同一台服务器上

java - 无法删除java中的哈希集

jakarta-ee - Jboss wildfly 如何绑定(bind)本地 JNDI namespace 中的条目?

java - 我应该使用@EJB 还是@Inject

java - 适用于多种用户类型的 Spring Security 和 Hibernate

java - 未找到 WildFly 9.0.1 WFLYCTL0158 处理程序 "CONSOLE"

java - 使用java在cmd中执行多个命令

java - 从 session 范围检索 @Named 托管 bean

transactions - CDI交易管理