使用Jersey/JAXB/Jackson将Java.util.Map映射到JSON对象
我一直在尝试创建一个Jersey REST Web服务。我希望从Java类接收和发出JSON对象,如下所示:使用Jersey/JAXB/Jackson将Java.util.Map映射到JSON对象,java,json,rest,jersey,jackson,Java,Json,Rest,Jersey,Jackson,我一直在尝试创建一个Jersey REST Web服务。我希望从Java类接收和发出JSON对象,如下所示: @XmlRootElement public class Book { public String code; public HashMap<String, String> names; } 然而,我找不到一个标准的解决方案。每个人似乎都在实现自己的目标。这一要求对我来说似乎非常基本;我不敢相信这是普遍接受的解决方案,特别是因为Jersey是Java中
@XmlRootElement
public class Book {
public String code;
public HashMap<String, String> names;
}
然而,我找不到一个标准的解决方案。每个人似乎都在实现自己的目标。这一要求对我来说似乎非常基本;我不敢相信这是普遍接受的解决方案,特别是因为Jersey是Java中更有趣的部分之一
我还尝试升级到Jackson 1.8,它只提供了以下内容,这是非常模糊的JSON:
{
"code": "ABC123",
"names": {
"entry": [{
"key": "de",
"value": "Die fabelhafte Welt der Amelie"
},
{
"key": "fr",
"value": "Le fabuleux destin d'Amelie Poulain"
}]
}
}
对此有什么建议的解决方案吗?您可以使用。下面是一个示例代码:
@Test
public void testGson(){
Book book = new Book();
book.code = "1234";
book.names = new HashMap<String,String>();
book.names.put("Manish", "Pandit");
book.names.put("Some","Name");
String json = new Gson().toJson(book);
System.out.println(json);
}
@测试
公共void testGson(){
书=新书();
book.code=“1234”;
book.names=新的HashMap();
书。名。字(“曼尼什语”、“潘迪特”);
书。名字。放(“一些”,“名字”);
字符串json=new Gson().toJson(book);
System.out.println(json);
}
输出是{“code”:“1234”,“Name”:{“Some”:“Name”,“Manish”:“Pandit”}
当然,对于书中的每个属性,都需要有getter/setter
另外,建议使用包装类(通常是一个映射)的原因是为了避免为要发送的每种数据创建多个DTO。使用映射进行序列化/反序列化,并作为业务逻辑的一部分,将其转换为相应的POJO进行内部处理更容易,特别是当您使用该POJO进行对象关系映射时。我不知道为什么这不是默认设置,我花了一段时间才弄明白,但是如果您想使用Jersey进行JSON转换,请添加
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
com.sun.jersey.api.json.POJOMappingFeature
真的
到您的web.xml,您的所有问题都应该得到解决
PS:您还需要去掉
@XmlRootElement
注释才能使其正常工作我知道很久以前就有人问过这个问题,但随着时间的推移,情况发生了变化,因此对于最新的Jersey v2.22,不再有com.sun.Jersey包,在项目中添加的这两个依赖项pom.xml解决了相同的问题:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.5.4</version> <!-- jackson version used by jersey v2.22 -->
</dependency>
谢谢,但我对与Jersey集成的解决方案特别感兴趣。我更喜欢这种返回复杂数据结构的方法,而不是简单的POJO。它可以完美地工作,它与Jersey集成(您只需要在get方法中返回一个“字符串”),并且您不必处理转换器的web.xml。提示+1。但是请注意,POJO映射也将在JSON中返回空值。我更喜欢JAXB并使用包含额外POJO的列表。这是服务器端设置。要在客户端上执行此操作,请执行以下操作:ClientConfig ClientConfig=new DefaultClientConfig();clientConfig.getFeatures().put(JSONConfiguration.FEATURE\u POJO\u映射,Boolean.TRUE);Client=Client.create(clientConfig)@Jan如果我需要将Book转换为json和xml(带有accepts的请求),该怎么办?如果我删除XmlRootElement,xml序列化将不再有效。这将是一个很好的答案,除了向web.xml添加建议之外,无论是否删除@XmlRootElement和相关注释,都会导致:com.sun.jersey.spi.container.ContainerRequest getEntity严重:Java类com.hp.web.user.dto.ProfileDto的消息体读取器和Java类型类com.hp.web.user.dto.ProfileDto,和MIME媒体类型应用程序/json;charset=UTF-8没有找到。是的,Russ说的。此非解决方案会出现“未找到邮件正文编写器”错误
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.5.4</version> <!-- jackson version used by jersey v2.22 -->
</dependency>
@JsonInclude(JsonInclude.Include.NON_NULL)