Клиент JAX-RS Jersey обрабатывает ответ JSON с помощью POJO MAPPING & Jackson

У меня возникла небольшая проблема с использованием клиента Jersey (1.11) с параметром JSONConfiguration.FEATURE_POJO_MAPPING, установленным в true. Мой тестовый код выглядит следующим образом:

MyFooCollectionWrapper resp
    = webResource.accept(MediaType.APPLICATION_JSON)
      .get(new GenericType>() {});

На сервере:

1) в моем файле web.xml значение POJO Mapping равно true.

2) MyFooDTO — это просто POJO, который выглядит так:

public class MyFooDTO {

private long id;
private String propA;

pubic long getId() {
    return id;
}
public void setId(long id) {
    this.id = id;
}

pubic String getPropA() {
    return propA;
}
public void setPropA(String propA) {
    this.propA = propA;
}

public MyFooDTO(MyFoo aFoo) {
    this.id = aFoo.getId();
    this.propA = aFoo.getPropA();
}

    public MyFooDTO() {}

}

3) MyFooCollectionWrapper выглядит так:

public class MyFooCollectionWrapper extends MyFooCollectionWrapperBase {

    Collection aCollection;

    public MyFooCollectionWrapper() {
        super();
    }

    public MyFooCollectionWrapper(boolean isOK, String msg, Collection col) {
        super(isOK, msg);
        this.aCollection = col;
    }

    public void setCollection(Collection collection) {
        this.aCollection = collection;
    }

    @JsonProperty("values")
    public Collection getCollection() {
        return aCollection;
    }
}

public class MyFooCollectionWrapperBase {

    private boolean isOK;
    private String message;

    public MyFooCollectionWrapperBase() {
        this.message = "";
        this.isOK = false;
    }

    public MyFooCollectionWrapperBase(boolean ok, String msg) {
        this.isOK = ok;
        this.message = msg;
    }

    .. standard getter/setters ..

}

Я проверил, что у сервера нет проблем с созданием ответа Json. Я могу получить с помощью моего клиентского кода из Джерси, если я установлю тип ответа на String. Когда я использую

MyFooCollectionWrapper resp = webResource.accept(MediaType.APPLICATION_JSON).get(new GenericType>() {});

, я ожидаю, что сопоставление POJO будет просто работать (упорядочивать ответ) без какой-либо необходимости в специальном считывателе тела сообщения.Тем не менее, я получаю:

Jun 04, 2012 3:02:20 PM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: A message body reader for Java class com.foo.MyFooCollectionWrapper, and Java type     com.foo. MyFooCollectionWrapper, and MIME media type application/json was not found
Jun 04, 2012 3:02:20 PM com.sun.jersey.api.client.ClientResponse getEntity
SEVERE: The registered message body readers compatible with the MIME media type are:
application/json ->
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$App
com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$App
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
*/* ->
com.sun.jersey.core.impl.provider.entity.FormProvider
com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider
com.sun.jersey.core.impl.provider.entity.StringProvider
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
com.sun.jersey.core.impl.provider.entity.FileProvider
com.sun.jersey.core.impl.provider.entity.InputStreamProvider
com.sun.jersey.core.impl.provider.entity.DataSourceProvider
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
com.sun.jersey.core.impl.provider.entity.ReaderProvider
com.sun.jersey.core.impl.provider.entity.DocumentProvider
com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$General
com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$General
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
com.sun.jersey.core.impl.provider.entity.EntityHolderReader
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General
com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy
com.sun.jersey.moxy.MoxyMessageBodyWorker
com.sun.jersey.moxy.MoxyListMessageBodyWorker


com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class com.foo.MyFooCollectionWrapper, and Java type com.foo. MyFooCollectionWrapper, and MIME media type application/json was not found
  at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:550)
  at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:524)
  at com.sun.jersey.api.client.WebResource.handle(WebResource.java:686)
  at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:74)
  at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:508)

Путь к классу на клиентской стороне теста включает в себя:

jersey-test-framework-core-1.11.jar 
jersey-test-framework-embedded-glassfish-1.11.jar 
jersey-test-framework-grizzly-1.11.jar 
jersey-test-framework-http-1.11.jar 
jersey-test-framework-inmemory-1.11.jar 
jackson-core-asl.jar 
jackson-jaxrs.jar 
jackson-xc.jar 
jackson-client.jar 
jersey-client.jar 
jersey-core.jar 
jersey-json.jar 
jettison.jar

Являются ли мои ожидания неправильными или я упустил что-то очевидное здесь?

В качестве примечания: если я добавляю аннотации JAXB к своим объектам (@XmlRootElement на MyFooCollectionWrapper и MyFooDTO), используя тот же вызов get webResource, клиент I не получает исключение чтения тела сообщения, однако ответ маршалируется таким образом, MyFooCollectionWrapper выглядит нормально, но его коллекция не содержит MyFooDTO, она содержит XML-документ с правильными значениями в узлах/атрибутах — другими словами, MyFooDTP не подвергается маршалингу.

При установке java.util.logging в CONFIG, как было предложено в ответе, я вижу следующее, хотя ничего не приходит мне в голову. Вот ссылка на вывод, которую я поместил на pastebin из-за длины.

Спасибо,

-Noah

ОБНОВЛЕНИЕ - РЕШЕНО

Первоначально мой клиент и конфигурация клиента создавались так:

Client rootClient = new Client();
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
Client client = new Client(rootClient, clientConfig);

Когда я изменил это на просто

    ClientConfig clientConfig = new DefaultClientConfig();
    clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
    Client client = Client.create(clientConfig);

Все заработало. Похоже, rootClient переопределял clientConfig на новом клиенте. Кажется странным, что когда вы используете конструктор, который указывает ClientConfig, ClientConfig переопределяется конфигурацией rootClients.

5
задан Jin Kwon 10 February 2015 в 13:43
поделиться