JSONObject 作为 POJO 中的成员变量无法识别 -Jersey

JSONObject as a member variable in POJO not recognized -Jersey

我正在构建 RESTful 网络服务。我一直处于无法继续的境地。我有一个 DAO(一个 POJO),它有一个 JSONObject 作为成员变量。当我尝试从客户端(Postman 或用户定义的 javascript)进行 POST 调用并尝试调试时,JSONObject 的 getter 中收集的值是空的({}) 而 class 的其他成员获得它们适当的值。我已经尝试用 @XmlElement@JsonProperty 等注释 JSONObject 及其 getter。没有任何效果。

class 看起来像:

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 对杰克逊的依赖

                        <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 支持添加 jackson-datatype-json-org

下面是一个完整的测试。这是我用来测试的依赖项

<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 2.16 使用的 Jackson 版本相同。如果您使用的是此球衣杰克逊的不同版本,您需要确保它引入的杰克逊版本与您正在使用的 jackson-datatype-json-org 版本相同。这样我们就不会混合 Jackson 版本。

这是使用 Jersey Test Framework

的测试
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 支持的依赖项。

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.16</version>
</dependency>

还要注意测试中的ObjectMapperProvider。您需要用 ObjectMapper 注册 JsonOrgModule 以便 Jackson 能够处理 JSONObject。这个很重要。如果您没有 ContextResolver,上面的示例将失败。