从 HttpSessionListener 获取 SessionScoped bean?

发布于 2024-10-20 16:47:19 字数 2996 浏览 1 评论 0原文

嘿伙计们。我试图在 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();
            }
        } 
    }

To 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");
    }
}

Hey guys. I'm trying to get a session bean in a HttpSessionListener so that when the user logs out or the session expires I can delete some files that the user created in the application. I'm guessing the session bean doesn't exist because the session is destroyed. I was hoping to still delete these files some how. Thanks for the help.

   @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();
            }
        } 
    }

To BalusC: I'm back to the method you previously had in mind. Streaming the bytes to the user wasn't flexible in my application. I found that I needed to do a lot of things in ajax on the page that was not possible if I had to send a non ajax request to stream a file to be downloaded. This way the heavy lifting is done with an ajax call(generating the document) and the fast and easy work is can be done with a non ajax call.

   @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");
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

泪之魂 2024-10-27 16:47:19

这段代码应该可以正常工作。请注意,FacesContext 不一定可用,因为此时运行的线程中不一定有 HTTP 请求的方法,但您已经对此进行了注释。您确定您实际上正在运行问题中所示的代码吗?清理、重建、重新部署等。

另一种方法是让您的 UserSessionBean 实现 HttpSessionBindingListener 然后在 valueUnbound() 方法。

@ManagedBean
@SessionScoped
public class UserSessionBean implements HttpSessionBindingListener {

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        for (File file : files) {
            file.delete();
        }
    }

    // ...
}

This code should work fine. Note that the FacesContext isn't necessarily available there since there's not necessarily means of a HTTP request in the thread running at that point, but you already outcommented that. Are you sure that you was actually running the code as shown in the question? Clean, rebuild, redeploy, etc.

An alternative is to let your UserSessionBean implement HttpSessionBindingListener and then do the job in the valueUnbound() method.

@ManagedBean
@SessionScoped
public class UserSessionBean implements HttpSessionBindingListener {

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        for (File file : files) {
            file.delete();
        }
    }

    // ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文