I've been trying to create a Jersey REST Webservice. I want to receive and emit JSON objects from Java classes like the following:
我一直在尝试创建一个Jersey REST Webservice。我想从Java类接收和发送JSON对象,如下所示:
@XmlRootElement
public class Book {
public String code;
public HashMap<String, String> names;
}
This should be converted into JSON like this:
应该将其转换为JSON:
{
"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.
但是我找不到一个标准的解决方案。每个人似乎都在实现自己的包装器解决方案。这个要求对我来说非常基本;我无法相信这是普遍接受的解决方案,尤其是因为Jersey是Java中更有趣的部分之一。
I've also tried upgrading to Jackson 1.8 which only gives me this, which is extremly obfusicated JSON:
我也试过升级到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"
}]
}
}
Are there any proposed solutions for this?
有什么解决方案吗?
4 个解决方案
#1
23
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
我不知道为什么这不是默认设置,我花了一段时间才弄明白,但是如果您想使用Jersey进行JSON转换,请添加
<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.
你的网络。应该解决xml和所有问题。
PS: you also need to get rid of the @XmlRootElement
annotations to make it work
PS:您还需要去掉@XmlRootElement注解才能使它正常工作
#2
7
You can use google-gson. Here is a sample code:
您可以使用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);
}
The output is {"code":"1234","names":{"Some":"Name","Manish":"Pandit"}}
输出是{“代码”:“1234”,“名字”:{“一些”:“名称”、“资源”:"潘迪特" } }
#3
4
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:
我知道很久以前就有人问过这个问题了,但是事情的发展意味着时间的改变,所以对于最新的Jersey v2.22来说,它再也没有包裹了。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>
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.
不需要在web.xml中添加任何内容。第一个依赖项将指示jersey对POJO到JSON转换使用jackson。第二个依赖项将注册jackson为jersey JSON提供者。
Also for the null problem in POJO, add this annotation to the POJO class:
对于POJO中的空问题,将此注释添加到POJO类:
@JsonInclude(JsonInclude.Include.NON_NULL)
#4
-2
@POST
@Consumes("application/json")
public void createBook(Book book)
{
.....
.....
}
Of course you need to have getter/setter for every property in Book.
当然,您需要为Book中的每个属性设置getter/setter。
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.
另外,推荐使用包装类(通常是map)的原因是为了避免为要发送的每种数据创建多个dto。使用映射来序列化/反序列化更容易,并且作为业务逻辑的一部分,将其转换为相应的POJO进行内部处理,特别是如果您使用POJO进行对象关系映射。
#1
23
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
我不知道为什么这不是默认设置,我花了一段时间才弄明白,但是如果您想使用Jersey进行JSON转换,请添加
<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.
你的网络。应该解决xml和所有问题。
PS: you also need to get rid of the @XmlRootElement
annotations to make it work
PS:您还需要去掉@XmlRootElement注解才能使它正常工作
#2
7
You can use google-gson. Here is a sample code:
您可以使用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);
}
The output is {"code":"1234","names":{"Some":"Name","Manish":"Pandit"}}
输出是{“代码”:“1234”,“名字”:{“一些”:“名称”、“资源”:"潘迪特" } }
#3
4
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:
我知道很久以前就有人问过这个问题了,但是事情的发展意味着时间的改变,所以对于最新的Jersey v2.22来说,它再也没有包裹了。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>
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.
不需要在web.xml中添加任何内容。第一个依赖项将指示jersey对POJO到JSON转换使用jackson。第二个依赖项将注册jackson为jersey JSON提供者。
Also for the null problem in POJO, add this annotation to the POJO class:
对于POJO中的空问题,将此注释添加到POJO类:
@JsonInclude(JsonInclude.Include.NON_NULL)
#4
-2
@POST
@Consumes("application/json")
public void createBook(Book book)
{
.....
.....
}
Of course you need to have getter/setter for every property in Book.
当然,您需要为Book中的每个属性设置getter/setter。
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.
另外,推荐使用包装类(通常是map)的原因是为了避免为要发送的每种数据创建多个dto。使用映射来序列化/反序列化更容易,并且作为业务逻辑的一部分,将其转换为相应的POJO进行内部处理,特别是如果您使用POJO进行对象关系映射。