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>
* <listener>
* <listener-class>com.example.SessionCleanupListener</listener-class>
* </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
中注册。好的,我也会尝试。