JSONObject как переменная-член в POJO не распознана -Джерси

Я создаю RESTful веб-сервис. Я был заблокирован в ситуации, когда я не могу продолжить. У меня есть DAO (POJO), который имеет JSONObject как переменная-член. Когда я пытаюсь сделать POST-вызов от клиента (Postman или пользовательский javascript) и пытаюсь отладить, значение, полученное в получателе JSONObject пусто ({}), тогда как другие члены класса получают свои соответствующие значения. Я пытался аннотировать JSONObject и его добытчик с @XmlElement, @JsonProperty и так далее.. ничего не получалось.

Класс выглядит так:

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);


}`

1 ответ

Решение

Проблема в том, что Джексон не знает, как создать JSONObject (по крайней мере, не без посторонней помощи). Джексон в основном работает с базовым типом и POJO. Если вы хотите быть в состоянии справиться JSONObject (при условии, что это объект из org.json), вы можете добавить 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 та же самая версия Джексона, используемая jersey-media-json-jackson 2,16. Если вы используете другую версию этого джерси Джексона, вам нужно убедиться, что версия Джексона, в которую он входит, совпадает с версией jackson-datatype-json-org ты используешь. Таким образом, мы не смешиваем версии Джексона.

Вот тест с использованием 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 в тесте. Вам нужно это зарегистрировать JsonOrgModule с ObjectMapper для того, чтобы Джексон мог справиться JSONObject, Это важно. Если у вас нет ContextResolver приведенный выше пример не удастся.

Другие вопросы по тегам