如何修复不可序列化的对象不应存储在 "HttpSession" 个对象中 (squid:S2441)

How to Fix Non-serializable objects should not be stored in "HttpSession" objects (squid:S2441)

我遇到了 Sonarqube 缺陷

Non-serializable objects should not be stored in "HttpSession" objects (squid:S2441)

为节省Httpsession,代码:

public static HttpSession setSessionAttribute(final HttpSession session, 
final String attributeName,
        final Object attributeValue) {
    session.setAttribute(attributeName, attributeValue);
    return session;
  }

作为属性添加到 HttpSession 的所有对象都必须是可序列化的(以便会话是可序列化的),

SonarQube 搜索 HttpSession 上的每个 setAttribute 对象是原始对象或实现可序列化,Code:

if (!type.isPrimitive() && !type.isSubtypeOf("java.io.Serializable")) { 
      addIssue(argument, "Make \"" + type + "\" serializable or don't store it in the session."); 
    } 

还有一个 issue 报告,应该在版本中修复 4.2 处理数组。

如果您可以修复代码,请将 attributeValue 更改为 Serializable

public static HttpSession setSessionAttribute(final HttpSession session, 
final String attributeName,
        final Serializable attributeValue) {
    session.setAttribute(attributeName, attributeValue);
    return session;
  }

Non-serializable objects should not be stored in "HttpSession" objects (squid:S2441)

合规解决方案:为了使会话复制起作用,应用程序在会话中存储为属性的值必须实现可序列化接口。

public class Address implements Serializable {
  //...
}

//...
HttpSession session = request.getSession();
session.setAttribute("address", new Address());  // Compliant; Address is serializable

CWE-579: J2EE Bad Practices: Non-serializable Object Stored in Session leads to replication problem across multiple JVMs

一个 J2EE 应用程序可以使用多个 JVM 来提高应用程序的可靠性和性能。为了使多个 JVM 对最终用户显示为单个应用程序,J2EE 容器可以跨多个 JVM 复制一个 HttpSession 对象,这样如果一个 JVM 变得不可用,另一个 JVM 可以介入并在不中断应用程序流程的情况下取而代之。这只有在所有会话数据都是可序列化的情况下才有可能,从而允许在 JVM 之间复制会话。

集群复制传输器示例tomcat-5.5, hazelcast.org.


表格Sonar-Java source of SerializableObjectInSessionCheck

@Rule(key = "S2441")
public class SerializableObjectInSessionCheck extends AbstractMethodDetection {

  @Override
  protected void onMethodInvocationFound(MethodInvocationTree mit) {
    ExpressionTree argument = mit.arguments().get(1);
    Type type = argument.symbolType();
    if (!isSerializable(type)) {
      String andParameters = isParametrized(type) ? " and its parameters" : "";
      reportIssue(argument, "Make \"" + type + "\"" + andParameters + " serializable or don't store it in the session.");
    }
  }
}