Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在序列化之前从会话中删除属性_Java_Session_Jakarta Ee - Fatal编程技术网

Java 在序列化之前从会话中删除属性

Java 在序列化之前从会话中删除属性,java,session,jakarta-ee,Java,Session,Jakarta Ee,我在用户会话中保存了一些链接到不可序列化对象的引用。 我想在应用程序关闭之前、会话序列化之前从会话中删除这些属性 有没有办法做到这一点? 我已经尝试使用侦听app destroy的侦听器,但此时会话已经无效。您可以创建第二个类,将第一个不可序列化的对象封装到对象引用中,并将其标记为transient: public class Wrapper implements Serializable { public transient YourClass obj; } transient变量在

我在用户会话中保存了一些链接到不可序列化对象的引用。 我想在应用程序关闭之前、会话序列化之前从会话中删除这些属性

有没有办法做到这一点?
我已经尝试使用侦听app destroy的侦听器,但此时会话已经无效。

您可以创建第二个类,将第一个不可序列化的对象封装到对象引用中,并将其标记为
transient

public class Wrapper implements Serializable
{
    public transient YourClass obj;
}
transient
变量在序列化时不会被序列化,在对
包装器
对象进行反序列化后,它将被分配给
null

您可以在
会话将钝化
方法中使用并实现清理逻辑

/**
 * Clean-up listener for removing non-serializable session attributes from session.
 * <p>
 * To activate simply register this class as servlet listener in {@code web.xml}:
 * <pre>
 * &lt;listener>
 *     &lt;listener-class>com.example.SessionCleanupListener&lt;/listener-class>
 * &lt;/listener>
 * </pre>
 */
public class SessionCleanupListener implements HttpSessionListener, HttpSessionActivationListener, Serializable {

    private static final long serialVersionUID = 1L;

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        // Register self as session attribute to get `passivation` events
        se.getSession().setAttribute(this.getClass().getName(), this);
    }

    @Override
    public void sessionWillPassivate(HttpSessionEvent se) {
        HttpSession session = se.getSession();
        Enumeration<String> names = session.getAttributeNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            if (!(session.getAttribute(name) instanceof Serializable)) {
                session.removeAttribute(name);
            }
        }
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        // no-op
    }

    @Override
    public void sessionDidActivate(HttpSessionEvent se) {
        // no-op
    }

}
/**
*清理侦听器以从会话中删除不可序列化的会话属性。
*
*要激活,只需在{@code web.xml}中将该类注册为servlet侦听器:
* 
*听众>
*listener类>com.example.SessionCleanupListener/listener类>
*/listener>
* 
*/
公共类SessionCleanupListener实现HttpSessionListener、HttpSessionActivationListener、Serializable{
私有静态最终长serialVersionUID=1L;
@凌驾
已创建公共无效会话(HttpSessionEvent se){
//将self注册为会话属性以获取“钝化”事件
se.getSession().setAttribute(this.getClass().getName(),this);
}
@凌驾
public void sessionwillpassiveate(HttpSessionEvent se){
HttpSession session=se.getSession();
枚举名称=session.getAttributeNames();
while(names.hasMoreElements()){
String name=names.nextElement();
if(!(session.getAttribute(name)instanceof Serializable)){
session.removeAttribute(名称);
}
}
}
@凌驾
public void sessionDestroyed(HttpSessionEvent se){
//无操作
}
@凌驾
公共无效SessionDiActivate(HttpSessionEvent se){
//无操作
}
}

我试图侦听这些事件,但在用户会话序列化之前没有调用它。@PacDroid此侦听器存在的唯一目的是侦听(反)序列化事件。你确定你说的是同一个监听器(JEE规范中与会话相关的监听器太少了)?是的,这很奇怪,我设置了一个类来实现ServletContextListener、HttpSessionActivationListener、HttpSessionListener和要实现的相关方法。我登录每一个,但并不是所有方法都在会话生命周期或会话传递/激活时被调用…您需要将此对象添加到会话。。。此侦听器仅在设置为会话属性时有效。您可以将它添加到中,它在
web.xml
中注册。好的,我也会尝试。