我有一个示例对象(包含在下面),旨在与 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": [
]
}
我再次从头开始实现这个示例,这次不小心忘记了制作
directories
final
,它神奇地工作了。我已经能够确认删除最终关键字会产生预期结果。很高兴知道