2014-11-25 2 views
4

Я сохранил некоторые ссылки в пользовательских сеансах, которые ссылаются на объекты, которые не являются сериализуемыми. Я хотел бы удалить эти атрибуты из сеанса до закрытия приложения, до сериализации сеанса.Удалить атрибут из сеанса перед сериализацией

Есть ли способ сделать это? Я уже пробовал с прослушивателем, который слушает приложение для уничтожения, но сеансы уже недействительны в тот момент.

ответ

5

Вы можете сделать второй класс, который оборачивает ваш первый несериализуемый в ссылку на объект, и пометить его как transient:

public class Wrapper implements Serializable 
{ 
    public transient YourClass obj; 
} 

transient переменные не будет сериализовать при сериализации, и он будет назначен до null после deserializarion Wrapper объект.

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> 
* &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 
    } 

} 
+0

Я попытался прослушать эти события, но он не вызывается перед сериализацией сеансов пользователя. – PacDroid

+0

@PacDroid Единственная цель этого слушателя - прослушивание события (сериализации). Вы уверены, что говорите о том же слушателе (в JEE spec есть более чем несколько слушателей, связанных с сеансом)? –

+0

Да, это странно, я создал класс, который реализует ServletContextListener, HttpSessionActivationListener, HttpSessionListener и связанные с ним методы для реализации. Я регистрирую каждый из них, но не все методы вызывают в жизненном цикле сеанса или сеансе pass/activate ... – PacDroid

Смежные вопросы