Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.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 tomcat会话不可序列化为带有@Value injection的spring组件_Java_Spring_Session_Tomcat_Serialization - Fatal编程技术网

Java tomcat会话不可序列化为带有@Value injection的spring组件

Java tomcat会话不可序列化为带有@Value injection的spring组件,java,spring,session,tomcat,serialization,Java,Spring,Session,Tomcat,Serialization,这是一个相当奇怪的问题。在春季,我将bean配置为会话 @Component @Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS) public class UserSession implements Serializable{...} public class UserInterceptor extends HandlerInterceptorAdapter{ ... @Autowired priva

这是一个相当奇怪的问题。在春季,我将bean配置为会话

@Component
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class UserSession implements Serializable{...}
public class UserInterceptor extends HandlerInterceptorAdapter{
    ...
    @Autowired private UserSession userSession;
    @Autowired private WebUser webUser;

    public boolean preHandle(...){
        userSession.setUserId(webUser.getUserId());
        userSession.setUserList(webUser.getUsers());
        ...
    }
...
}
有一个与此会话交互的拦截器

@Component
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class UserSession implements Serializable{...}
public class UserInterceptor extends HandlerInterceptorAdapter{
    ...
    @Autowired private UserSession userSession;
    @Autowired private WebUser webUser;

    public boolean preHandle(...){
        userSession.setUserId(webUser.getUserId());
        userSession.setUserList(webUser.getUsers());
        ...
    }
...
}
WebUser
是一个界面,根据环境的不同,它将在其中注入不同的
WebUser
。在profile
LOCAL
中,In将注入
LocalWebUser

@Component
@Primary
@Profile({"LOCAL"})
public class LocalWebUser implements WebUser, Serializable{
   @Autowired private transient UserManager userManager;

   @Value("${env.tester.userId}")
   private transient String userId;

   @Override
   public List<String> getUsers() {
       return this.userManager.getUsers();
   }
   ...
}
@组件
@初级的
@配置文件({“本地”})
公共类LocalWebUser实现WebUser,可序列化{
@自动连线的私有瞬态用户管理器;
@值(${env.tester.userId}”)
私有临时字符串用户标识;
@凌驾
公共列表getUsers(){
返回这个.userManager.getUsers();
}
...
}
注意,我确实将make字段设置为
transient
,以防止常见的序列化问题。然而,在tomcat中,它抛出
LocalWebUser
是不可序列化的

原因:java.io.NotSerializableException: com.company.component.web.LocalWebUser$1 位于java.io.ObjectOutputStream.WriteObject 0(ObjectOutputStream.java:1164) 位于java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518) 位于java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)

LocalWebUser
实际上并没有存储在session中,只是session从中检索值。为什么它抱怨它不可序列化


我确实找到了一个解决方案,通过从属性中删除
@Value
注入
,异常消失了,这让我更加困惑……

一种可能是@Value注释通过字节码操作将
userId
字段的类型修改为其他不可序列化的类型

因此,当您调用
userSession.setUserId(webUser.getUserId())
时,它会将不可序列化的类型复制到userSession

然而,我找不到任何关于@Value注释的参考来支持这一点,所以这只是一种预感


您可能可以通过在运行时使用调试器检查
userId
字段的类型来验证这一点。

它不是在抱怨
LocalWebUser
。它在抱怨
LocalWebUser$1
,这是
LocalWebUser
中的一个匿名内部类。查看
LocalWebUser
中的代码,了解类似以下内容:

Object something = new Something() { .... };

这是一个匿名的内部类。如果这是不可序列化的,并且对它的引用正在泄漏到会话中存储的对象中,那么这就是您的问题。

wow。很好的观察。getUsers()上有一些guava转换,它将
new Function()
,这可能是原因?也许是。您是否能够在任何地方看到生成的代码,或者Guava是否编译为内存字节码?