我有一个ID列表,我需要将其作为参数传递以JSON格式显示。具体来说,我将值放在列表中,并希望我的GET方法将其返回为:
[ 1, 5, 12,...]
我尝试使用GenericList,但收到MessageBodyWriter错误:
MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.List<java.lang.Long>.
我使用的是Jersey 2.16,输出自定义类列表没有问题。代码在这里:
@GET
@Path("{name}")
@Produces(MediaType.APPLICATION_JSON)
public Response getUsersByName(@PathParam("name") String name){
List<Long> userIds = userService.getUserssByName(name);
GenericEntity<List<Long>> list = new GenericEntity<List<Long>>(userIds){};
return Response.ok(list).build();
}
UserService查询名称与某个名称匹配的所有用户的哈希图,并返回其键列表:
public List<Long> getUserssByName(String name){
List<Long> ids = new ArrayList<>();
for (Entry<Long, User> entry : users.entrySet()){
User user = entry.getValue();
if (user.getName().equals(name)){
ids.add(entry.getKey());
}
}
return ids;
}
我如何才能如上所述显示该列表?
最佳答案
我认为这个解释性的答案比仅仅“修复”代码更好。
默认情况下,jersey提供了一组可用于给定媒体类型的实体提供程序。对于application/json
,默认情况下提供以下类型:
byte[]
String
InputStream
Reader
File
DataSource
StreamingOutput
要添加对其他类型的序列化到json的支持,使用当前正在使用的工具有些困难。我会解释...
Jersey只是一个用Java开发RESTful Web服务的框架。曾经有一段时间REST不存在(或被认为没有用),在这个概念出现之前,已经有许多具体的实现方式可以促进Http数据传输。 JAX-RS是其中之一。当时JavaScript可能还处于起步阶段,而XML在很大程度上统治着万维网。 JAX-RS并不是为防止类型擦除而设计的,而类型擦除正是我们要实现的目标。对我来说,要想通过在MessageBodyWriter中实现行为的极其冗长的解决方案,就是要重新发明轮子,没有人喜欢重新发明轮子!但是,如果您有兴趣编写自己的实体,或者有兴趣了解什么是实体以及如何自定义它们,请转到https://jersey.java.net/documentation/latest/message-body-workers.html。阅读本文档将概述您的问题到底发生了什么。
解
选择一项服务。学习它,不要重新发明轮子。有许多服务可以实现此目的。我最喜欢的工具是Gson。这是Google开发的Java库,用于将Java对象转换为其JSON表示,反之亦然。
想知道修复代码的简单程度吗?
@GET
@Path("{name}")
@Produces(MediaType.APPLICATION_JSON)
public Response getUsersByName(@PathParam("name") String name){
List<Long> userIds = userService.getUserssByName(namee);
Type listType = new TypeToken<List<Long>>() {}.getType();
Gson gson = new Gson();
String userIdList = gson.toJson(userIds, listType);
return Response.ok(userIdList).build();
}
现在,jersey支持String实体响应的application / json。您几乎所有的响应都将表示为String,防止类型擦除,并且您将成为一个更满意的开发人员。
希望这可以帮助!