Java 无法识别作为POJO中成员变量的JSONObject-Jersey
我正在构建一个RESTful web服务。我陷入了一种无法继续的境地。我有一个DAO(POJO),它有一个Java 无法识别作为POJO中成员变量的JSONObject-Jersey,java,json,jersey,jackson,jsonobject,Java,Json,Jersey,Jackson,Jsonobject,我正在构建一个RESTful web服务。我陷入了一种无法继续的境地。我有一个DAO(POJO),它有一个JSONObject作为成员变量。当我尝试从客户端(邮递员或用户定义的javascript)进行POST调用并尝试调试时,JSONObject的getter中收集的值为空({}),而类的其他成员则获取相应的值。我试着用@xmlement,@JsonProperty等注释JSONObject及其getter。。什么都没用 该类看起来像: package org.somepackage imp
JSONObject
作为成员变量。当我尝试从客户端(邮递员或用户定义的javascript)进行POST调用并尝试调试时,JSONObject
的getter中收集的值为空({}),而类的其他成员则获取相应的值。我试着用@xmlement
,@JsonProperty
等注释JSONObject
及其getter。。什么都没用
该类看起来像:
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
}
}
}
}
依赖关系 对Jackson的web.xml依赖性
<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>
问题是Jackson不知道如何创建
JSONObject
(至少在没有帮助的情况下是这样)。Jackson主要处理基本类型和POJO。如果您希望能够处理JSONObject
(假设这是org.json
中的对象),您可以为Jackson支持添加
下面是一个完整的测试。以下是我用来测试的依赖项
<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 JSON支持只需要一个依赖项
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.16</version>
</dependency>
org.glassfish.jersey.media
泽西媒体公司
2.16
还要注意测试中的
ObjectMapperProvider
。为了让Jackson能够处理JSONObject
,您需要使用ObjectMapper
注册JsonOrgModule
。这很重要。如果您没有ContextResolver
,上述示例将失败。创建另一个嵌套的POJO类来表示JSONObject中的数据,对于任意数据格式,只需使用Map
而不是JSONObject
谢谢@peeskillet,我听从了您的建议,但运气不佳。不管对象的内容是什么,它仍然被解析为空的JSONObject
。你知道还有别的办法吗?我需要以JSON
的形式使用信息,是否可以使用Map
来进行此操作?共享您与POST一起传递的正文和标题API@peeskillet! JSON结构看起来像这样:{“name”:“ABCD”,“ID”:“P63784433”,“theJSON”:{“string”:“foo”,“number”:5,“array”:[1,2,3],“object”:{“property”:“value”,“subobj”:{“arr”:[“foo”,“ha”],“numero”:1}}}}}
@kyle,我在这条评论上面贴了正文。同样关于头,我返回了一个如下形式的响应:response.ok(someString,MediaType.APPLICATION\u JSON)。status(201)。header(CorsHeaderConstants.header\u AC\u ALLOW\u METHODS,“GET POST DELETE PUT”)。header(CorsHeaderConstants.header\u AC\u ALLOW\u CREDENTIALS,“true”)。header(CorsHeaderConstants.header\u AC\u ALLOW\u ORIGIN,“*”)。header(CorsHeaderConstants.HEADER\u AC\u ALLOW\u ORIGIN,“*”).ALLOW(“OPTIONS”).build()
我想提一下,我的POST API一直在为其他类型的POJO工作,我只使用了一个包含JSONObject的POJO!非常感谢。根据您的建议,我添加了ObjectMapperProvider
类,用于注册JsonOrgModule
。如何将其与someClass链接e> ?@vardhinisuresh27您不需要链接任何东西。只要注册了ObjectMapperProvider
,它就应该可以工作,如我完整的可运行/可测试示例所示谢谢。但我从您的测试代码中看到configure()
函数注册了ObjectMapperProvider
。那么在我的案例中,我该如何进行类似的操作呢?我不知道,您还没有展示您的案例。我不知道您如何注册所有的资源类和提供程序。您是否使用包扫描?如果是,扫描应该选择@Provider
注释and为您注册它,只要该类在要扫描的包或子包中列出。同时请记住,您应该删除您在帖子中的所有Jackson依赖项。只需使用我在回答中的一个即可
<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>
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
= "{\n"
+ " \"firstName\": \"pee\",\n"
+ " \"lastName\": \"skillet\",\n"
+ " \"other\": {\n"
+ " \"age\": 100,\n"
+ " \"birthday\": \"yesterday\"\n"
+ " }\n"
+ "}";
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"));
}
}
}
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.16</version>
</dependency>