Jsonb.fromJson 不会反序列化由 Jsonb.toJson(objectWithSet) 生成的 JSON 字符串生成的 Set

问题描述 投票:0回答:1

我有一个示例对象(包含在下面),旨在与 JAXB、JSON-B 和 JPA 一起使用。我已经编写了一些单元测试来验证输出,但 JSON-B 给我带来了一些麻烦。当我反序列化刚刚序列化的对象时,产品不匹配。也就是说,即使 Set 被很好地序列化,它也不会被反序列化。

我从 JAXB 开始,并能够让它按预期工作。 我必须创建 Directory 类才能正确处理 Set,然后创建 XmlJavaTypeAdapter 来处理 Path。

因为它似乎只是以一种方式进行,所以我尝试创建一个

JsonbDeserializer<Set<ArtifactDirectory>>
但使用
new JsonbConfig().withDeserializers(new DirectorySetDeserializer())
似乎不起作用。事实上它甚至根本没有使用这个类。

这个想法是能够通过 REST 对 JAXB、JSON 和 JPA 使用一个对象,事实证明这比我想象的要复杂得多。

我添加了单元测试,让我更有信心

@POST
@Consumes({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
public Response persistReview(Review review) {
    ...
}

将按预期工作。 (当然不是)

Maven POM:

<dependency>
    <groupId>jakarta.json.bind</groupId>
    <artifactId>jakarta.json.bind-api</artifactId>
    <version>3.0.1</version>
</dependency>
<dependency>
    <groupId>org.eclipse</groupId>
    <artifactId>yasson</artifactId>
    <version>3.0.2</version>
</dependency>

目录类(包含在Set中):

@XmlAccessorType(XmlAccessType.FIELD)
public class Directory {
    @XmlElement
    @XmlJavaTypeAdapter(ArtifactDirectoryTranslator.class)
    private Path path;

    public Directory() {}
    
    public Directory(Path path) {
        this.path = path;
    }

    public Path getPath() {
        return path;
    }

    public void setPath(Path path) {
        this.path = path;
    }
}

JAXB/JSONB/实体类:

@XmlRootElement(name = "review")
@XmlAccessorType(XmlAccessType.FIELD)
public class Review {
    @XmlElementWrapper(name = "artifact-directories")
    private final Set<Directory> directories = new HashSet<>();
    
    public Review addDirectory(Path dirPath) {
        directories.add(new Directory(dirPath));
        return this;
    }
    
    public Set<Directory> getDirectories() {
        return directories;
    }
    
    public void setDirectories(Set<Directory> directories) {
        // done this way for JPA/Hibernate
        this.directories.clear();
        this.directories.addAll(directories);
    }
}

单元测试:

@Test
public void testJsonb() {
    Review uut_review = new Review();
    uut_review.addDirectory(Path.of("/some/path/1"));
    uut_review.addDirectory(Path.of("/some/path/2"));

    JsonbConfig config = new JsonbConfig().withFormatting(true);
    Jsonb jsonb = JsonbBuilder.newBuilder().withConfig(config).build();
    
    // totally fine: {"directories":[{"path": "/some/path/1"}, {"path": "/some/path/2"}]}
    String jsonResult = jsonb.toJson(uut_review);
    System.out.println(jsonResult);    

    // not so good: {"directories":[]}
    Review actualReivew = jsonb.fromJson(jsonResult, Review.class);
    String jsonResult2 = jsonb.toJson(actualDataReivew);
    System.out.println(jsonResult2);
}

单元测试输出:

{
    "directories": [
        {
            "path": "/some/path/1"
        },
        {
            "path": "/some/path/2"
        }
    ]
}
{
    "directories": [
    ]
}
java json jsonb jsonb-api
1个回答
0
投票

我再次从头开始实现这个示例,这次不小心忘记了制作

directories
final
,它神奇地工作了。我已经能够确认删除最终关键字会产生预期结果。很高兴知道

© www.soinside.com 2019 - 2024. All rights reserved.