gpt4 book ai didi

java - 强制 JAX-RS 将我的类序列化为 JSON 对象

转载 作者:行者123 更新时间:2023-11-30 11:06:45 24 4
gpt4 key购买 nike

我有一个类,它是围绕内部列表的装饰器。我想在我的 JAX-RS 服务中将此类用作 DTO。其代码如下:

@XmlRootElement(name = "movies")
public class MoviesResponse implements List<Movie> {

@XmlElement(name = "movie")
protected List<Movie> movies;

/* tons of delegate methods */

}

我需要同时支持 application/xml 和 application/json。格式是固定的,必须是这样的

<movies>
<movie>
<foo />
</movie>
<movie>
<foo />
</movie>
</movies>

...在 XML 中,和

{
"movie": [
{},{}
]
}

...在 JSON 中。XML 工作得很好,但 JSON 看起来像这样:

[{},{}]

您可能会怀疑,如果我不实现 List 接口(interface),它会生成我需要的格式。所以我猜序列化器很聪明,把它当作列表来序列化成一个数组。但是我需要将它序列化为一个对象。我该怎么做,实现 List 接口(interface)?

最佳答案

假设 Jackson 是您的序列化程序,您可以将 ObjectMapper 配置为 WRAP_ROOT_VALUE .你会在 ContextResolver 中这样做.为了不对所有类型使用相同的配置,您可以使用两个不同的配置 ObjectMapper,一个用于列表类,一个用于其余类。例如

@Provider
public class ObjectMapperContextResolver implements ContextResolver<ObjectMapper> {

final ObjectMapper listMapper = new ObjectMapper();
final ObjectMapper defaultMapper = new ObjectMapper();

public ObjectMapperContextResolver() {
listMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
listMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);

listMapper.registerModule(new JaxbAnnotationModule());
defaultMapper.registerModule(new JaxbAnnotationModule());
}

@Override
public ObjectMapper getContext(Class<?> type) {
if (type == MovieList.class) {
return listMapper;
}
return defaultMapper;
}
}

MessageBodyWriter用于编码的将调用 getContext 方法,传入它试图编码的类。根据结果​​,这就是将要使用的 ObjectMapperWRAP_ROOT_VALUE 所做的是将根值包装在一个对象中,名称是 @JsonRootName@XmlRootElement 中的值(给定 JAXB 注释支持已启用 - 请参阅 here )

测试:

@Path("/movies")
public class MovieResource {

@GET
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response getMovieList() {
MovieList list = new MovieList();
list.add(new Movie("I Origins"));
list.add(new Movie("Imitation Game"));
return Response.ok(list).build();
}
}

C:\>curl -v -H "Accept:application/json" http://localhost:8080/api/movies
Result:
{
"movies" : [ {
"name" : "I Origins"
}, {
"name" : "Imitation Game"
} ]
}

更新

所以我注意到您的列表是protected。也许您以后可能想要扩展 MovieList 类。在这种情况下,这

if (type == MovieList.class) {
return listMapper;
}

机器人是可行的。相反,您需要检查类型是 isAssignableFrom

if (MovieList.class.isAssignableFrom(type)) {
return listMapper;
}

关于java - 强制 JAX-RS 将我的类序列化为 JSON 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29198237/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com