2

我正在尝试使用 CDI 实现登录机制@javax.enterprise.context.SessionScoped

代码:

@Named
@SessionScoped
public class Auth implements Serializable {

  private User user;

  @Inject
  private UserStore userStore;

  @Produces @CurrentUser
  public User getUser() {
    if (user == null) {
        Principal principal= FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();

            if (principal != null) {

                Map parameters = new HashMap();
                parameters.put("email", principal.getName());

                user = (User) userStore.findWithNamedQuery(User.GET_BY_EMAIL, parameters).get(0);
            }
        }

        return user;
    }

    public void logout() throws IOException {
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        ec.invalidateSession();
        ec.redirect(ec.getRequestContextPath() + "/");
    }
}

总是接收相同User实例的类:

@Stateful
public class NewsService implements Serializable {

    @Inject @CurrentUser
    private User currentUser;

    @Inject
    private NewsStore newsStore;

    public List<News> getNewsForLoggedUser(Integer start, Integer limit) {
        Map<String, Object> params = new HashMap<>();
        params.put("user", currentUser);

        return (List<News>) newsStore.findWithNamedQuery(News.getAllForUser, params, start, limit);
    }
}

方法有问题getUser()。即使会话无效,它仍然会从第一次登录时返回值。如何销毁 CDI bean 或更改它以使其始终输出实际值?我尝试了注释logout()方法@PreDestroy,但它会产生这样的错误:

13:20:50,329 ERROR [org.jboss.weld.Bean] (default task-22) WELD-000019 Error destroying an instance Managed Bean [class com.intenso.presentation.Auth] with qualifiers [@Default @Any @Named] of com.intenso.presentation.Auth@59821e

我在 WildFly 8.0.0.Alpha4 上运行

4

2 回答 2

4

问题可能来自您的生产者没有明确的范围,因此它具有@Dependent伪范围。这意味着生产者代码在您的 EJB 构建时被调用一次,并且 Injected 值在您的所有 EJB 生命周期中保持不变。

你没有提到你的@StatefulEJB 是如何使用的,但我假设它被注入到另一段代码中,所以你的代码比请求保持更长的时间。

为了纠正你的错误,你应该给你的生产者一个正常的范围(@RequestScoped似乎是最好的选择)。所以你的生产者代码将变成

@Produces @CurrentUser @RequestScoped
public User getUser() { ... }

请记住,生产者不会从包含它的 bean 继承范围。在这个正常范围内,userbean 不会被直接注入,但 CDI 会注入它的代理。因此,currentUser只有在当前请求的生命周期内才会保持不变。

不要犹豫,阅读CDI 1.1 规范的依赖范围章节,它很有帮助

于 2013-10-11T08:04:15.783 回答
0

我以前也遇到过类似的问题,我觉得你的会话页面被缓存了,你可以通过这样做来清除它们

HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Cache-Control", "no-cache,no-store,must-revalidate");          // HTTP 1.1
httpResponse.setHeader("Pragma", "no-cache"); // HTTP 1.0
httpResponse.setDateHeader("Expires", 0); // Proxies.
chain.doFilter(request, response);

在您的 FilterServlet 中。

于 2013-10-10T20:41:39.570 回答