【发布时间】:2017-12-09 09:33:03
【问题描述】:
我有一个简单的 web-app maven 项目,其结构如下:
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类是一个拦截器接口,代码如下:
@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 bean,我测试并发现它是正确的。
对于这个例子,我们讨论的是一个 servlet,所以我带着以下问题来找你:
1) 如果我的 servlet(我的示例中的那个)不被视为 CDI bean,为什么当我设置 @Logger 拦截器时有效?
2) 为什么我的 servlet 中的拦截器 @Logger 在方法级别不起作用,而在类级别却可以正常工作?
在方法级别使用注释进行调试我看到 servlet 已包装,但由于某种原因,@AroundInvoke 方法被忽略了。
【问题讨论】:
-
您确定 doGet() 在您的注释处于类级别时被拦截,还是像构造函数一样被拦截?您应该从调用上下文中记录更多信息或签入调试器。
-
是的,在方法级别拦截,我确认一下
标签: java wildfly cdi interceptor