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

时间:2011-04-26 18:22:24

标签: java json rest jersey jackson

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

@XmlRootElement
public class Book {

    public String code;

    public HashMap<String, String> names;

}

这应该像这样转换成JSON:

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

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

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

4 个答案:

答案 0 :(得分:24)

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

    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

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

PS:您还需要删除@XmlRootElement注释才能使其正常工作

答案 1 :(得分:7)

您可以使用google-gson。以下是示例代码:

    @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);
   }

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

答案 2 :(得分:4)

我知道它很久以前就被问过了,但事情发生了变化,所以对于最新的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>

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

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

@JsonInclude(JsonInclude.Include.NON_NULL)

答案 3 :(得分:-2)

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

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

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