У меня возникла небольшая проблема с использованием клиента 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.