我正在尝试使用Jersey创建一个非常简单的REST服务。这是服务代码
@Path("/UserService")
public class UserService {
@GET
@Path("/users")
@Produces(MediaType.APPLICATION_XML)
public List<User> getUsers() {
User user = new User(1, "Thomas", "Greene");
List<User> userList = new ArrayList<User>();
userList.add(user);
return userList;
}
}
当我通过Postman运行它时,它返回一个XML响应
现在,我想得到一个JSON响应。因此,我将媒体类型更改为application/json
:
@Path("/UserService")
public class UserService {
@GET
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
public List<User> getUsers(){
User user = new User(1, "Thomas", "Greene");
List<User> userList = new ArrayList<User>();
userList.add(user);
return userList;
}
}
它在Tomcat日志中给了我下面的错误:
SEVERE:对于media type=application/json,type=class java.util.ArrayList,genericType= java.util. List,找不到MessageBodyWriter。
有人能教我如何得到一个JSON响应吗?
6条答案
按热度按时间p8h8hvxi1#
要使用Jackson2.x作为JSON提供程序,您需要将
jersey-media-json-jackson
模块添加到pom.xml
文件中:然后在
Application
/ResourceConfig
子类中注册JacksonFeature
。有关更多详细信息,请查看Jersey文档。
fcy6dtqo2#
目前我对JAXB绑定也有点不满,因此让我在这里总结一下我的发现-如果我说了什么愚蠢的话,请纠正我:
1.当然,你必须有一个库来做JSON(反)序列化,在我的情况下,它是Moxy。
1.您必须告诉JAXB它应该支持哪些类。有多种方法可以做到这一点,最简单的方法似乎是在与类匹配的目录中添加一个 jaxb.properties 文件,其唯一内容是文本 javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory。对于目录,我的意思是,如果你的类在目录 src/main/java 中,那里有包 com.pkg1.entities,将这个文件添加到 src/main/resources 中,那里有 *com/pkg 1/entities/jaxb.properties *。
1.默认情况下,JAXB适用于POJO。所以你需要一个没有参数的构造函数,一个get和一个set方法。只有这样,这个字段才会出现在JSON中。
1.我经常做的是添加第二个构造函数,该构造函数获取传入的运行时对象,并将所有字段设置为直接公开。因此,我不需要也不想要一个集合方法。解决方案是使用 @XmlElement 注解get方法。
1.我说过你需要一个空的/默认的构造函数吗?我花了三个小时才弄清楚为什么class 1工作正常,class 2得到了MessageBodyWriter错误。我忘记了建造者。呃。
1.当类配置得很好,但是它的一个字段返回了一个它不能序列化的类型时,你会得到同样的错误(我相信)。
1.我相信有一种情况是类注解 @XmlRootElement 导致了这个错误。不确定,但我现在很少使用这个注解。
1.如果您将List作为要转换为Json数组的元素之一,JAXB将使用myAbstract类进行序列化。不是很有用,你希望实际的对象被序列化。但是JAXB如何知道是谁实现/扩展了这个类呢?您必须使用注解@XmlSeeAlso进行说明。所以MyAbstract类得到一个类注解 @XmlSeeAlso({MyConcrete1.class,MyConcrete2.class})。至少Moxy添加了一个额外的 type 字段,告诉消费者它是哪个类。完全说得通。
1.虽然可以返回 userList,但更好的选择是返回 Response.ok().entity(userList).build();你也可以返回错误。逻辑上是一样的。
1.注意你使用的数据类型。String可以,ArrayList也可以,Hashtable不行。也取决于您使用的序列化程序。
我希望这对其他人有帮助。
yzuktlbb3#
你需要一个json序列化器在你的类路径上来使它工作。
只要加上Jackson和泽西将使用这个作家。例如,如果您正在使用maven,请将其添加到pom.xml文件中。
slsn1g294#
你的xml是工作的,所以我假设你在你的
User
类中有@XmlRootElement
注解。问题是,它知道如何用注解
@XmlRootElement
将其转换为xml,但不知道如何将其转换为JSON。因此,为了使它将所有内容转换为JSON,我们可以添加相同的xml注解(即
@XmlRootElement
),jersey-media-moxy-<whatever version>.jar
或者对于maven用户
它还应该有一个无参数构造函数
3qpi33ja5#
我尝试了大量的依赖项,但没有一个适用于我的Jersey 3版本。我需要做的是把Arraylist变成一个实际的数组。我用
toArray()
管理这个,它开始正确地序列化!wh6knrhe6#
真实的问题是你需要把你的List放在一个类中,试试这个:
你的代码是这样的: