java - 寻找枚举反/序列化过程中这种奇怪行为的解释

标签 java jsonb-api

最近,我在枚举与 JSON 之间进行反/序列化时遇到了一个奇怪的行为。

我将相关部分简化为一个简单的示例(请参阅下面的代码)。基本上你有一个包含枚举条目的列表。您序列化列表,然后反序列化它。如果您检查新的(反序列化)列表是否包含某些枚举条目,您将始终得到“false”作为答案,即使该列表实际上包含该条目。

我自己分析了一下,发现反序列化列表后,内容不再是枚举类型,而是包含字符串。

我想了解为什么会发生这种情况以及如何避免它。我的目标是在反序列化后再次获得枚举条目列表,而不是字符串列表。

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.json.bind.JsonbBuilder;
import javax.json.bind.JsonbConfig;

public class Test {

    enum TYPE {
        SMALL, MEDIUM, LARGE
    }

    public static void main(String[] args) {

        List<TYPE> myList = new ArrayList<>();

        myList.add( TYPE.MEDIUM );

        // serialize
        String serializedJsonString = JsonbBuilder.create(new JsonbConfig().withLocale(Locale.GERMAN).withFormatting(true)).toJson(myList);

        // deserialize
        @SuppressWarnings("unchecked")
        List<TYPE> mySecondList = JsonbBuilder.create(new JsonbConfig().withLocale(Locale.GERMAN).withFormatting(true)).fromJson(serializedJsonString, List.class);

        System.out.println( myList.contains( TYPE.MEDIUM ) );       // will be true (as expected)

        System.out.println( mySecondList.contains( TYPE.MEDIUM ) ); // will be false (surprising!)
        System.out.println( mySecondList.contains( "MEDIUM" ) );    // will be true (surprising!)
    }
}

最佳答案

Java 枚举默认序列化为字符串,因为没有更好的默认 JSON 类型。 (如果您愿意,可以将它们配置为序列化为整数。)

反序列化时,必须指示 Jsonb 解析器将 JSON 字符串转换为枚举,否则默认情况下会将它们反序列化为 Java 字符串。

在上面的示例中您没有这样做,因为您要求它提供 List.class (即 List<?> ),而不是 TYPE 的列表枚举( List<TYPE> )。由于类型删除,这在 Java 中很难做到。 (请注意,您必须将代码标记为“未选中”,因为编译器知道您的版本将无法工作。) JsonB 文档明确讨论了这种情况: http://json-b.net/docs/user-guide.html#mapping-a-generic-collection

尝试如下:

List<TYPE> mySecondList = jsonb.fromJson(result, new ArrayList<TYPE>(){}.getClass().getGenericSuperclass());

关于java - 寻找枚举反/序列化过程中这种奇怪行为的解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54073789/

相关文章:

java - 从服务器接收数据时出现 NoSuchElementFoundException

java - 使用远程调试运行 docker-compose。 Intellij,Java 11

java - 如何将十六进制值从 RGB 添加到 Jpanel

java - spring boot中如何访问pcf用户服务

java - While 循环不检查所有条件

java - 我如何知道 Java 类型是否可以从 JSON 转换为 JSON

jakarta-ee - 除了@JsonbIgnore,是否可以要求在 jax-rs (jersey+moxy) JSON 序列化上显式包含对象的字段?

java - 如何防止 eclipse Yasson 输出空字符串和空集合