我在用户会话中保存了一些引用,这些引用链接到不可序列化的对象。 我希望在应用程序关闭之前,在会话序列化之前从会话中删除这些属性。
有没有办法这样做? 我已经尝试使用监听器来监听app destroy,但是当时会话已经失效。
答案 0 :(得分:5)
您可以创建第二个类,将第一个非序列化包装到对象引用中,并将其标记为transient
:
public class Wrapper implements Serializable
{
public transient YourClass obj;
}
transient
变量在序列化后不会被序列化,并且在null
对象的反序列化后将被分配到Wrapper
。
答案 1 :(得分:0)
您可以使用HttpSessionActivationListener
并在sessionWillPassivate
方法中实现清理逻辑。
/**
* 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
}
}