使用Jersey / JAXB / Jackson的Java.util.Map到JSON对象

我一直在尝试创建Jersey REST Web服务。 我想从Java类接收和发出JSON对象,如下所示:

@XmlRootElement public class Book { public String code; public HashMap names; } 

这应该像这样转换为JSON:

 { "code": "ABC123", "names": { "de": "Die fabelhafte Welt der Amelie", "fr": "Le fabuleux destin d'Amelie Poulain" } } 

但是我找不到一个标准的解决方案。 每个人似乎都在实施自己的包装 解决方案 。 这个要求对我来说似乎是极其基本的; 我无法相信这是普遍接受的解决方案,特别是因为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" }] } } 

对此有任何建议的解决方案吗?

我不知道为什么这不是默认设置,我花了一段时间搞清楚它,但是如果你想用Jersey进行JSON转换,添加

   com.sun.jersey.api.json.POJOMappingFeature true  

到你的web.xml,你的所有问题都应该解决。

PS:你还需要摆脱@XmlRootElement注释才能使它工作

你可以使用google-gson 。 这是一个示例代码:

  @Test public void testGson(){ Book book = new Book(); book.code = "1234"; book.names = new HashMap(); book.names.put("Manish", "Pandit"); book.names.put("Some","Name"); String json = new Gson().toJson(book); System.out.println(json); } 

输出为{"code":"1234","names":{"Some":"Name","Manish":"Pandit"}}

我知道它很久以前就被问过了,但事情发生了变化,所以对于最新的泽西岛v2.22,不再有com.sun.jersey包,在项目pom.xml中添加的这两个依赖项解决了同样的问题:

  org.glassfish.jersey.media jersey-media-json-jackson 2.22   com.fasterxml.jackson.jaxrs jackson-jaxrs-json-provider 2.5.4   

无需在web.xml中添加任何内容。 第一个依赖项将指示jersey使用jackson进行POJO到JSON转换。 第二个依赖项将jackson注册为jersey JSON提供者。

同样对于POJO中的null问题,将此注释添加到POJO类:

 @JsonInclude(JsonInclude.Include.NON_NULL) 
 @POST @Consumes("application/json") public void createBook(Book book) { ..... ..... } 

当然,你需要为Book中的每个属性设置getter / setter。

另外,为什么建议使用包装类(通常是地图)的原因是避免为要发送的每种数据创建多个DTO。 使用映射进行序列化/反序列化更容易,并且作为业务逻辑的一部分将其转换为相应的POJO以进行内部处理,尤其是在使用该POJO进行对象关系映射时。