使用 Jersey / JAXB / Jackson 将 Java.util.Map 映射到 JSON 对象

发布于 2024-11-03 14:39:34 字数 1049 浏览 0 评论 0原文

我一直在尝试创建 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 解决方案。这个要求对我来说似乎是极其基本的;我不敢相信这是普遍接受的解决方案,特别是因为 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"
        }]
    }
}

是否有任何建议的解决方案?

I've been trying to create a Jersey REST Webservice. I want to receive and emit JSON objects from Java classes like the following:

@XmlRootElement
public class Book {

    public String code;

    public HashMap<String, String> names;

}

This should be converted into JSON like this:

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

However I can not find a standard solution for this. Everybody seems to be implementing his own wrapper solution. This requirement seems extremly basic to me; I can't believe that this is the generally accepted solution to this, especially since Jersey is really one of the more fun parts of Java.

I've also tried upgrading to Jackson 1.8 which only gives me this, which is extremly obfusicated JSON:

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

Are there any proposed solutions for this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

乙白 2024-11-10 14:39:34

我不知道为什么这不是默认设置,我花了一些时间才弄清楚,但如果您想使用 Jersey 进行 JSON 转换,请添加

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

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

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

I don't know why this isn't the default setting, and it took me a while figuring it out, but if you want working JSON conversion with Jersey, add

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

to your web.xml and all your problems should be solved.

PS: you also need to get rid of the @XmlRootElement annotations to make it work

挽梦忆笙歌 2024-11-10 14:39:34

您可以使用 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"}}

You can use google-gson. Here is a sample code:

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

The output is {"code":"1234","names":{"Some":"Name","Manish":"Pandit"}}

月下凄凉 2024-11-10 14:39:34

我知道很久以前就有人问过这个问题,但事情发生了变化,因此对于不再有包 com.sun.jersey 的最新 Jersey v2.22,在项目中添加了这两个依赖项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 注册为球衣 JSON 提供程序。

同样针对POJO中的null问题,在POJO类中添加此注解:

@JsonInclude(JsonInclude.Include.NON_NULL)

I know it's been asked long time ago, but things changed mean time, so for the latest Jersey v2.22 that do not have anymore the package com.sun.jersey, these two dependencies added in the project pom.xml solved the same problem:

<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>

No need to add anything in web.xml.
First dependency will instruct jersey to use jackson for POJO to JSON transformations.
Second dependency will register jackson as jersey JSON provider.

Also for the null problem in POJO, add this annotation to the POJO class:

@JsonInclude(JsonInclude.Include.NON_NULL)
月光色 2024-11-10 14:39:34
@POST
@Consumes("application/json")
public void createBook(Book book)
{
 .....
 .....
}

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

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

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

Of course you need to have getter/setter for every property in Book.

Also the reason as why it is recommended to use wrapper class (which is usually a map) is to avoid creating multiple DTOs for every kind of data you want to send. It is easier to just serialize/deserialize using a map and as part of business logic convert it to a corresponding POJO for internal processing particularly if you are using that POJO for object relational mapping.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文