容器是Glassfish。我在一个简单的DAO bean类中实现了一个@PostConstruct
生命周期事件拦截器方法,但似乎由于某种原因它根本没有拦截我的业务方法。我没有在任何地方手动实例化bean类。 beans.xml
发现模式就是全部,因为我没有注释DefaultUserDao
bean,所以它获得了默认范围。
public class DefaultUserDao implements UserDao {
private String userName;
private String password;
Scanner users = null;
String[] userNamePasswordPairs = null;
public DefaultUserDao() {
try {
users = new Scanner(Paths.get("/home/nhuyvan1106/NetBeansProjects/EJBInAction/web/users"));
}
catch (IOException ex) {
Logger.getLogger(DefaultUserDao.class.getName()).log(Level.SEVERE, null, ex);
}
}
/*The interceptor for this method is defined right below, that
interceptor method is not called at all. If I insert a
System.out.println(userNamePasswordPairs) after the split()
method below, it prints [userName:password] pair twice and there
is only one line in the text file from which the pair was read in the
form like this admin:admin. Notice that I also insert a System.out.println()
method in the interceptor method but if I remove the print()
method from this init() method, I don't see it prints anything
*/
@PostConstruct
public void init() {
while (users.hasNextLine()) {
String line = users.nextLine();
userNamePasswordPairs = line.split(":");
//If I uncomment this, I see it prints [admin:admin] pair
//twice, but when I comment it out, I don't see it prints anything
//System.out.println(Arrays.toString(userNamePasswordPairs));
userName = userNamePasswordPairs[0];
password = userNamePasswordPairs[1];
}
}
@AroundConstruct
private void printUser(InvocationContext ic) {
//If this interceptor was invoked, it should print at least "Interceptor invoked: "
//But it does not print this.
System.out.println("Interceptor invoked: " + Arrays.toString(userNamePasswordPairs));
try {
ic.proceed();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
收集用户名和密码的简单JSF页面
@Named
@RequestScoped
public class LoginBean {
private String userName;
private String password;
@Inject
private UserDao userDao;
public LoginBean() {
}
public LoginBean(String userName, String password) {
this.userName = userName;
this.password = password;
}
public String validateUser() {
if (userDao.getUserName().equals(userName) && userDao.getPassword().equals(password)) {
}
else {
userName = "Error";
password = "Error";
}
return "confirmation.xhtml";
}
//getter and setter for userName and password
}
答案 0 :(得分:0)
首先,请注意@PostContruct
是生命周期回调 - 而不是拦截器 - 而@AroundConstruct
是拦截器方法。它们有不同的含义,并以不同的方式声明。
另请注意,调用顺序通常如下:
proceed()
方法调用构造函数。@Inject
字段/设置器)@PostConstruct
生命周期回调。关于@PostConstruct
生命周期回调,您可以正确声明它。它似乎被打电话,因为它打印了一些文字。
关于拦截器,缺少以下内容:
META-INF/beans.xml
元素 OR 下的<interceptors>
文件中声明,必须使用指定优先级值的javax.annotations.Priority
注释进行注释。后面的选项基本上使你的拦截器在应用程序范围内:它将应用于整个应用程序,而不仅仅是包含META-INF/beans.xml
的jar。首先,我建议您在META-INF/beans.xml
。@Interceptor
(javax.interceptor.Interceptor
)总而言之,您必须为拦截器创建一个拦截器绑定:
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface Greet {
}
然后你必须使用拦截器绑定为你的拦截器创建一个类:
@Greet
@Interceptor
public class GreetInterceptor {
@AroundConstruct
public void aroundConstruct(InvocationContext ic) throws Exception {
System.out.println("Hello!!");
ic.proceed();
}
}
然后在META-INF/beans.xml
:
<interceptors>
<class>com.sandbox.GreetInterceptor</class>
</interceptors>
最后,使用拦截器绑定注释要拦截调用的bean:
@Greet
public class DefaultUserDao implements UserDao {
...
}