Java 在会话中存储对象并在新部署后尝试访问它时捕获ClassCastException?

Java 在会话中存储对象并在新部署后尝试访问它时捕获ClassCastException?,java,session,tomcat,classcastexception,runtimeexception,Java,Session,Tomcat,Classcastexception,Runtimeexception,我面临的情况是,如果我在会话中存储了一个表单,在对war进行新部署并尝试访问该表单之后,我会得到一个java.lang.ClassCastException 为了让这对用户透明,我编写了以下代码: try { command = (ReservationOfBooksCommand) request.getPortletSession().getAttribute(RESERVATION_OF_BOOKS_COMMAND_SESSION_NAME); } catch (C

我面临的情况是,如果我在会话中存储了一个表单,在对war进行新部署并尝试访问该表单之后,我会得到一个java.lang.ClassCastException

为了让这对用户透明,我编写了以下代码:

try {
        command = (ReservationOfBooksCommand) request.getPortletSession().getAttribute(RESERVATION_OF_BOOKS_COMMAND_SESSION_NAME);
    } catch (ClassCastException e) {
        request.getPortletSession().removeAttribute(RESERVATION_OF_BOOKS_COMMAND_SESSION_NAME);
    }
但不确定是否有更优雅的替代方案,因为我不喜欢捕捉运行时异常,也不想每次部署新war时都重新启动服务器


谢谢。

一些应用服务器允许在重新部署之前清除会话。例如,将继续为旧会话使用旧代码,将新会话移动到新代码上。显然,您需要在某个时候终止用户会话。

您可以使用instanceof操作符

Object command = request.getPortletSession().getAttribute(RESERVATION_OF_BOOKS_COMMAND_SESSION_NAME);

if(!(command instanceof ReservationOfBooksCommand)){
        request.getPortletSession().removeAttribute(RESERVATION_OF_BOOKS_COMMAND_SESSION_NAME);
}else{
   ...
}

既然您已经用
tomcat
标记了这个问题,我建议您:

  • 在您自己的web应用程序中创建一个
    META-INF/context.xml
  • 在context.xml中添加以下代码行
  • 样本:

    <context>
        <!-- stuff here-->
    
        <!-- Persistence Manager. This handles all of session Tomcat handles from our app. -->
        <Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="false">
            <Store className="org.apache.catalina.session.FileStore" /> 
        </Manager>
    
    </context>
    
    
    
    正如michaelbarker所说,默认情况下,大多数应用服务器在重新部署后都会清理请求和会话

    要允许Tomcat存储会话,请设置
    saveOnRestart=“true”
    。这允许tomcat使用
    PersistentManager
    将会话存储在
    FileStore
    中(也就是说,使用文件存储系统而不是数据库存储系统)


    希望这能有所帮助。

    Hi@Elite Genister,我想说的是,我不希望每次重新部署时都重新启动,尽管我可以在重新启动之间保持会话。@Juan Carlos Blanco Martínez,不幸的是,我不知道不重新启动就重新部署,因为你的对象需要在应用服务器类加载器中注册。好的,我使用的Liferay具有插件(如Portlet、themes…)的热部署功能,因此我的情况涉及Portlet插件的重新部署不确定是否是最佳解决方案,但至少我认为它比我的更优雅。让我们看看是否会有更多的选择:)