JSONObject作为POJO中的成员变量无法识别-Jersey [英] JSONObject as a member variable in POJO not recognized -Jersey
问题描述
我正在构建一个RESTful Web服务。我一直处于无法继续下去的境地。我有一个DAO(POJO),它有一个 JSONObject
作为成员变量。当我尝试从客户端(Postman或用户定义的javascript)进行POST调用并尝试调试时,在 JSONObject
的getter中收集的值为空({} )而班级的其他成员获得适当的价值。我已经尝试用 @XmlElement
, @JsonProperty JSONObject
及其getter code>依此类推。没有任何效果。
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;
}
}
感谢您的帮助!
谢谢。
I appreciate your help! Thanks.
编辑
示例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 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>
资源和提供商通过网络注册。 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);
}`
推荐答案
问题是杰克逊不知道如何创建 JSONObject
(至少没有一些帮助)。杰克逊主要处理基本类型和POJO。如果你想能够处理 JSONObject
(假设这是来自 org.json
的对象),你可以添加 jackson-datatype-json-org
杰克逊支持。
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
与 jersey-media-json-jackson
2.16使用的Jackson版本相同。如果你使用的是这个泽西杰克逊的不同版本,你需要确保它所引入的杰克逊版本是相同版本的 jackson-datatype-json-org
您正在使用。这样我们就不会混合杰克逊版本。
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
= "{\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"));
}
}
}
你还应该做的是摆脱上面评论中的所有杰克逊依赖关系。您只需要一个依赖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.
这篇关于JSONObject作为POJO中的成员变量无法识别-Jersey的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!