JSONObject 作为 POJO 中的成员变量无法识别 -Jersey
我正在构建一个 RESTful Web 服务.我被锁定在无法继续进行的情况下.我有一个以 JSONObject
作为成员变量的 DAO(一个 POJO).当我尝试从客户端(邮递员或用户定义的 javascript)进行 POST 调用并尝试调试时,JSONObject
的 getter 中收集的值为空({}),而其他成员该类获得其适当的值.我试过用 @XmlElement
、@JsonProperty
等注释 JSONObject
及其 getter.没有任何效果.
I'm building a RESTful web service. I've been locked in a situation where I'm not able to proceed. I've a DAO (a POJO) that has a JSONObject
as a member variable. When I try to make a POST call from client (Postman or user-defined javascript) and try to debug, the value gathered in the getter of the JSONObject
is empty ({}) whereas the other members of the class obtain their appropriate values. I've tried annotating the JSONObject
and its getter with @XmlElement
, @JsonProperty
and so on.. Nothing worked.
类看起来像:
package org.somepackage
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonProperty;
import org.json.JSONObject;
@XmlRootElement
public class someClass {
private String someID;
private String someName;
private JSONObject someJsonObject;
public someClass () {
}
public someClass (String id, String name,
JSONObject jsonObj) {
someID=id;
someName=name;
someJsonObject=jsonObj;
}
public String getSomeID() {
return someID;
}
public void setSomeID(String id) {
this.SomeID= id;
}
public String getSomeName() {
return someName;
}
public void setSomeName(String name) {
this.someName= name;
}
public JSONObject getSomeJsonObject() {
return someJsonObject;
}
public void setSomeJsonObject(JSONObject jsonObj) {
this.someJsonObject= jsonObj;
}
}
感谢您的帮助!谢谢.
编辑
示例 JSON
{
"name": "ABCD",
"ID": "P63784433",
"theJSON":{
"string":"foo",
"number":5,
"array":[1,2,3],
"object":{
"property":"value",
"subobj":{
"arr":["foo","ha"],
"numero":1
}
}
}
}
<小时>
依赖web.xml 对 Jackson 的依赖
DEPENDENCY web.xml dependency on Jackson
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-xc</artifactId>
<version>1.9.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.2</version>
</dependency>
<小时>
通过 web.xml 注册资源和提供者
<!-- Register JAX-RS Application -->
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>my.package.MyApplication</param-value>
</init-param>
<!-- Register resources and providers under my.package. -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>my.package</param-value>
</init-param>
<!-- Register custom provider -->
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>my.package.mapper.ObjectMapperProvider</param-value>
</init-param>`
<小时>
MyApplication.java
`@ApplicationPath("/")
public class MyApplication extends ResourceConfig {
public MyApplication() {
// Register resources and providers using package-scanning.
packages("my.package");
register(ObjectMapperProvider.class);
}`
推荐答案
问题是 Jackson 不知道如何创建 JSONObject
(至少在没有帮助的情况下不是这样).Jackson 主要处理基本类型和 POJO.如果您希望能够处理 JSONObject
(假设这是来自 org.json
的对象),您可以添加 jackson-datatype-json-org
支持 Jackson.
The problem is that Jackson doesn't know how to create the JSONObject
(at least not without some help). Jackson mainly handle basic type and POJOs. If you want to be able to handle JSONObject
(assuming this is the object from org.json
), you can add the jackson-datatype-json-org
for the Jackson support.
下面是一个完整的测试.这是我用来测试的依赖项
Below is a complete test. Here are the dependencies I used to test
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20141113</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.16</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-json-org</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>2.16</version>
<scope>test</scope>
</dependency>
注意:我用于 jackson-datatype-json-org
的 Jackson 版本与 jersey-media-json-jackson 使用的 Jackson 版本相同
2.16.如果你使用的是这个 jersey jackson 的不同版本,你需要确保它引入的 Jackson 版本与你使用的 jackson-datatype-json-org
版本相同.这样我们就不会混合 Jackson 版本.
Note: The Jackson version I am using for jackson-datatype-json-org
is the same Jackson version used by jersey-media-json-jackson
2.16. If you are using a different version of this jersey jackson, you will need to make sure the version of Jackson it pulls in is the same version of jackson-datatype-json-org
you are using. This way we are not mixing Jackson versions.
这是使用 Jersey 测试框架
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.json.JSONObject;
import org.junit.Test;
import static junit.framework.Assert.*;
/**
*
* @author Paul Samsotha
*/
public class JsonOrgTest extends JerseyTest {
public static class Model {
public String firstName;
public String lastName;
public JSONObject other;
// should br private with correct getters and setters
}
@Path("model")
public static class ModelResource {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response post(Model model) {
return Response.ok(model).build();
}
}
@Provider
public static class ObjectMapperProvider implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public ObjectMapperProvider() {
mapper = new ObjectMapper();
mapper.registerModule(new JsonOrgModule());
}
@Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
@Override
public ResourceConfig configure() {
return new ResourceConfig(ModelResource.class)
.register(ObjectMapperProvider.class)
.register(JacksonFeature.class);
}
@Override
public void configureClient(ClientConfig config) {
config.register(JacksonFeature.class);
config.register(ObjectMapperProvider.class);
}
@Test
public void should_return_org_json_data() {
final String json
= "{
"
+ " "firstName": "pee",
"
+ " "lastName": "skillet",
"
+ " "other": {
"
+ " "age": 100,
"
+ " "birthday": "yesterday"
"
+ " }
"
+ "}";
Response response = target("model").request().post(Entity.json(json));
if (response.getStatus() != 200) {
System.out.println(response.getStatus() + ": " + response.readEntity(String.class));
fail("should return data and 200");
} else {
Model model = response.readEntity(Model.class);
JSONObject other = model.other;
System.out.println(other.toString());
assertEquals("pee", model.firstName);
assertEquals("skillet", model.lastName);
assertEquals(100, other.getInt("age"));
assertEquals("yesterday", other.getString("birthday"));
}
}
}
您还应该做的是摆脱所有您在上面评论中的 Jackson 依赖项.Jackson JSON 支持只需要一个依赖项.
What you should also do is get rid of all the Jackson dependencies you have in your comment above. You only need one dependency for Jackson JSON support.
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.16</version>
</dependency>
还要注意测试中的ObjectMapperProvider
.您需要通过 ObjectMapper
注册 JsonOrgModule
,以便 Jackson 能够处理 JSONObject
.这个很重要.如果你没有ContextResolver
,上面的例子就会失败.
Also notice the ObjectMapperProvider
in the test. You will need to this to register the JsonOrgModule
with the ObjectMapper
in order for Jackson to be able to handle JSONObject
. This is important. If you don't have the ContextResolver
, the above example will fail.
相关文章