【问题标题】:Getting SessionScoped bean from HttpSessionListener?从 HttpSessionListener 获取 SessionScoped bean?
【发布时间】:2011-07-11 11:30:33
【问题描述】:

大家好。我正在尝试在 HttpSessionListener 中获取会话 bean,以便当用户注销或会话到期时,我可以删除用户在应用程序中创建的一些文件。我猜会话 bean 不存在,因为会话被破坏了。我希望仍然以某种方式删除这些文件。感谢您的帮助。

   @WebListener
    public class SessionListener implements HttpSessionListener {

        @Override
        public void sessionCreated(HttpSessionEvent se) {
            HttpSession session = se.getSession();
            System.out.print(getTime() + " (session) Created:");
            System.out.println("ID=" + session.getId() + " MaxInactiveInterval="
                    + session.getMaxInactiveInterval());
        }

        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            HttpSession session = se.getSession();

            FacesContext context = FacesContext.getCurrentInstance();
            //UserSessionBean userSessionBean = (UserSessionBean) context.getApplication().evaluateExpressionGet(context, "#{userSessionBean}", UserSessionBean.class)
            UserSessionBean userSessionBean = (UserSessionBean) session.getAttribute("userSessionBean");

            System.out.println(session.getId());
            System.out.println("File size :" + userSessionBean.getFileList().size());

            for (File file : userSessionBean.getFileList()) {
                file.delete();
            }
        } 
    }

致 BalusC:我又回到了你之前想到的方法。在我的应用程序中,将字节流式传输给用户并不灵活。我发现我需要在页面上用 ajax 做很多事情,如果我必须发送非 ajax 请求来流式传输要下载的文件,这是不可能的。这样,繁重的工作是通过 ajax 调用(生成文档)完成的,而快速简单的工作可以通过非 ajax 调用来完成。

   @ManagedBean(name = "userSessionBean")
@SessionScoped
public class UserSessionBean implements Serializable, HttpSessionBindingListener {

    final Logger logger = LoggerFactory.getLogger(UserSessionBean.class);
    @Inject
    private User currentUser;
    @EJB
    UserService userService;
    private List<File> fileList;

    public UserSessionBean() {

        fileList = new ArrayList<File>();
    }

    @PostConstruct
    public void onLoad() {

        Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
        String email = principal.getName();

        if (email != null) {
            currentUser = userService.findUserbyEmail(email);
        } else {

            logger.error("Couldn't find user information from login!");
        }
    }

    public User getCurrentUser() {
        return currentUser;
    }

    public void setCurrentUser(User currentUser) {
        this.currentUser = currentUser;
    }

    public List<File> getFileList() {
        return fileList;
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {

        logger.info("UserSession unbound");
        logger.info(String.valueOf(fileList.size()));
        for (File file : fileList) {
            logger.info(file.getName());
            file.delete();
        }
    }

    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        logger.info("UserSessionBean bound");
    }
}

【问题讨论】:

    标签: java jsf jsf-2 httpsession servlet-listeners


    【解决方案1】:

    这段代码应该可以正常工作。请注意,FacesContext 不一定在那里可用,因为此时运行的线程中不一定意味着 HTTP 请求,但您已经对此发表了评论。您确定您实际上运行了问题中显示的代码吗?清理、重建、重新部署等。

    另一种方法是让您的UserSessionBean 实现HttpSessionBindingListener,然后在valueUnbound() 方法中完成这项工作。

    @ManagedBean
    @SessionScoped
    public class UserSessionBean implements HttpSessionBindingListener {
    
        @Override
        public void valueUnbound(HttpSessionBindingEvent event) {
            for (File file : files) {
                file.delete();
            }
        }
    
        // ...
    }
    

    【讨论】:

    • 嘿 BalusC 我也试过这个。我知道文件列表中有文件对象。我可以通过在我的应用程序中记录大小来测试它。但是,当调用 unbound 时,文件对象大小为 0。这与会话侦听器的问题相同。我已经用代码更新了我的原始帖子。我 100% 确定列表正在获取对象。
    • 我不知道。该列表是 userSessionBean 对象的一部分。我可以在应用程序中检索并添加到列表中。
    猜你喜欢
    • 1970-01-01
    • 2011-12-19
    • 2020-03-16
    • 2011-12-10
    • 2015-03-28
    • 1970-01-01
    • 2011-03-23
    • 2014-10-20
    • 1970-01-01
    相关资源
    最近更新 更多