java - Spring MVC : How to create single instance of object while deserialization JSON string containing duplicate object definitions

标签 java spring-mvc serialization jackson deserialization

我想使用 Spring MVC 将包含重复定义的 JSON 字符串反序列化为 java 对象。 要求是为这些重复定义创建对象的单个实例,而不是创建具有相同内容的重复对象。

示例类:

import java.io.Serializable;

public class Example implements Serializable {
    private String a;
    private String b;

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }

    public String getB() {
        return b;
    }

    public void setB(String b) {
        this.b = b;
    }
}

JSON 字符串:

[
  {
    "a": "a",
    "b": "b"
  },
  {
    "a": "a",
    "b": "b"
  },
  {
    "a": "a1",
    "b": "b1"
  }
]

我得到的输出:

 ExampleList=[
    Example@151c632a, 
    Example@5051613a, 
    Example@6212cffd
    ] 

创建了三个单独的对象。

我想要的输出是:

 ExampleList=[
    Example@1eda78db, 
    Example@1eda78db, 
    Example@68a94d19
    ] 

创建了 2 个对象(1eda78db 和 68a94d19),而不是 3 个。

我看到了一篇类似的文章,其中涉及实现readResolve(),但是有没有什么简单的方法可以做到这一点,并且内存较少? How can I link two Java serialised objects back together?

这是我想要解决的用例。 accountNameinfoTList 中的对象 accountTobjId0 相同。 我想要修改对象 accountT 并希望看到它在 objId0

中得到反射(reflect)
{
  "accountT": {
    "poidId0": 200,
    "poidDb": 1,
    "poidType": "/account",
    "poidRev": 10
  },
  "accountNameinfoTList": [
    {
      "id": {
        "recId": 1
      },
      "objId0": {
        "poidId0": 200,
        "poidDb": 1,
        "poidType": "/account",
        "poidRev": 10
      },
      "address": "2632 Marine Way",
      "canonCompany": "child corp",
      "canonCountry": "GB",
      "city": "Elstree",
      "company": "Child Corp"
    }
  ]
}

最佳答案

不确定这是否可以帮助其他人。 我能够通过利用 @JsonCreator

解决这个问题

我通过使用 @ JsonProperty 传递值创建了一个静态方法 createExample

public class Example implements Serializable {
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @JsonValue
    private String a;
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @JsonValue
    private String b;
    public Example() {
    }
    @JsonCreator
    public static Example createExample(@JsonProperty("a") String a,
                                        @JsonProperty("b") String b) {
        Example example = new Example();
        example.a = a;
        example.b = b;
        return (Example) ReferenceMap.findOriginalObject(example);
    }
}

ReferenceMap 保存 WeakHashMap 中的详细信息!

public class ReferenceMap {
    public static final String KEY_WEAK_REFERENCE_MAP = "weakReferenceMap";

    public static Object findOriginalObject(Object object) {
        Map<Object, Reference<Object>> weakReferenceMap = fetchWeakReferenceMapFromServletRequest();
        WeakReference<Object> originalReference = (WeakReference<Object>) weakReferenceMap.get(object);
        Object originalObject = originalReference == null ? null : originalReference.get();
        if (originalObject == null) {
            originalObject = object;
            weakReferenceMap.put(originalObject, new WeakReference<>(originalObject));
        }
        return originalObject;
    }

    private static Map<Object, Reference<Object>> fetchWeakReferenceMapFromServletRequest() {
        HttpServletRequest
                request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest();
        Object requestAttribute = request.getAttribute(KEY_WEAK_REFERENCE_MAP);
        if (requestAttribute == null) {
            Map<Object, Reference<Object>> weakReferenceMap = new WeakHashMap<>();
            requestAttribute = weakReferenceMap;
            request.setAttribute(KEY_WEAK_REFERENCE_MAP, weakReferenceMap);
        }
        return (Map<Object, Reference<Object>>) requestAttribute;
    }
}

有了这个,我确信总是会获得一个现有实例,而不是创建一个新实例。

更新 将 WeakHashMap 保存在 ServletRequestAttributes 中而不是 JVM 的堆中。

关于java - Spring MVC : How to create single instance of object while deserialization JSON string containing duplicate object definitions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61871139/

相关文章:

java - 不同类型 map 的 map

Java & Akka : Creating an actor B from actor A

java - Spring MVC : Avoiding file extension in URL

java - 只有最后一行被插入到 hibernate 表中

java - 一元运算与赋值融合

java - HTTP状态404请求的资源不可用-springMVC

java - Spring安全从更深层访问UserDetailsS​​ervice

c# - 反序列化具有多个元素属性的 XML 文件 - 属性不反序列化

java - Java序列化的解释

C#:存储非常相似的字符串项以高效序列化到文件的最佳集合类是什么