PUT проблемы с обработкой JSON с использованием JAXB под Jersey 2.2 с MOXy
Я застрял в этой проблеме в течение нескольких дней, и теперь я ищу некоторые рекомендации, чтобы помочь решить эту проблему. Я имею большой опыт работы с jax-w в Metro, но это мое первое приключение в jax-rs с Джерси. Чтобы упростить движущиеся части, я взял код jerssey-examples-moxy в качестве отправной точки.
Я изменил пример проекта, чтобы принять как XML, так и JSON. Я думал, что это будет просто, но я, кажется, что-то упустил, потому что это был болезненный опыт. Код выполняется без проблем, когда я запрашиваю "application/xml", и GET будет работать для "application/json", но когда я пытаюсь сделать PUT с JSON, сервер возвращает код состояния 500. Я вижу, что JSON отправляется в запросе PUT, но на сервере, похоже, возникла проблема с принятием JSON.
Вот модифицированный сегмент файла CustomerResource.java. Все, что я сделал, это добавил параметр MediaType.APPLICATION_JSON в аннотации Produces and Consumes.
@Path("/customer")
public class CustomerResource {
private static Customer customer = createInitialCustomer();
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Customer getCustomer() {
return customer;
}
@PUT
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public void setCustomer(Customer c) {
customer = c;
}
private static Customer createInitialCustomer() {
Customer result = new Customer();
result.setName("Jane Doe");
result.setAddress(new Address("123 Any Street", "My Town"));
result.getPhoneNumbers().add(new PhoneNumber("work", "613-555-1111"));
result.getPhoneNumbers().add(new PhoneNumber("cell", "613-555-2222"));
return result;
}
}
Я изменил файл MoxyAppTest.java для запроса XML и JSON MediaTypes в отдельных тестах:
@Test
public void testJaxBCustomer() throws Exception {
final WebTarget webTarget = target().path("customer");
Customer customer = webTarget.request(MediaType.APPLICATION_XML).get(Customer.class);
assertEquals("Jane Doe", customer.getName());
customer.setName("Tom Dooley");
Response response = webTarget.request(MediaType.APPLICATION_XML).put(Entity.xml(customer));
assertEquals(204, response.getStatus());
Customer updatedCustomer = webTarget.request(MediaType.APPLICATION_XML).get(Customer.class);
assertEquals(customer, updatedCustomer);
}
@Test
public void testJsonCustomer() throws Exception {
final WebTarget webTarget = target().path("customer");
Customer customer = webTarget.request(MediaType.APPLICATION_JSON).get(Customer.class);
assertEquals("Tom Dooley", customer.getName());
customer.setName("Bobby Boogie");
Response response = webTarget.request(MediaType.APPLICATION_JSON).put(Entity.json(customer));
assertEquals(204, response.getStatus());
Customer updatedCustomer = webTarget.request(MediaType.APPLICATION_JSON).get(Customer.class);
assertEquals(customer, updatedCustomer);
}
В файле App.java я добавил класс JsonMoxyConfigurationContextResolver и вызов registerInstances() в методе createApp(). (Обратите внимание, что это не изменит результат).
public static ResourceConfig createApp() {
return new ResourceConfig().packages("org.glassfish.jersey.examples.xmlmoxy")
.register(new MoxyXmlFeature())
.registerInstances(new JsonMoxyConfigurationContextResolver());
}
@Provider
final static class JsonMoxyConfigurationContextResolver implements ContextResolver<MoxyJsonConfig> {
@Override
public MoxyJsonConfig getContext(Class<?> objectType) {
final MoxyJsonConfig configuration = new MoxyJsonConfig();
Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);
namespacePrefixMapper.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
configuration.setNamespacePrefixMapper(namespacePrefixMapper);
configuration.setNamespaceSeparator(':');
return configuration;
}
}
Вот сегмент журнала, показывающий, что PUT "application / xml" был успешным со статусом 204:
Aug 23, 2013 1:23:50 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 3 * LoggingFilter - Request received on thread main
3 > PUT http://localhost:9998/customer
3 > Accept: application/xml
3 > Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<customer><personal-info><name>Tom Dooley</name></personal-info><contact-info><address><city>My Town</city><street>123 Any Street</street></address><phone-number type="work">613-555-1111</phone-number><phone-number type="cell">613-555-2222</phone-number></contact-info></customer>
Aug 23, 2013 1:23:50 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 4 * LoggingFilter - Response received on thread main
4 < 204
4 < Date: Fri, 23 Aug 2013 05:23:50 GMT
Теперь для журналов "application / json":
Aug 23, 2013 1:23:51 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 3 * LoggingFilter - Request received on thread main
3 > PUT http://localhost:9998/customer
3 > Accept: application/json
3 > Content-Type: application/json
{"personal-info":{"name":"Bobby Boogie"},"contact-info":{"address":{"city":"My Town","street":"123 Any Street"},"phone-number":[{"type":"work","value":"613-555-1111"},{"type":"cell","value":"613-555-2222"}]}}
Aug 23, 2013 1:23:51 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 4 * LoggingFilter - Response received on thread main
4 < 500
4 < Date: Fri, 23 Aug 2013 05:23:50 GMT
4 < Content-Length: 0
4 < Connection: close
Как вы можете видеть, сервер возвращает код состояния 500. Тестовый контейнер Grizzly не генерирует журнал, фиксирующий любую информацию об исключениях, и похоже, что в ответе 500 ничего не возвращается. Есть ли способ получить дополнительную информацию об исключении?
Любые предложения о том, как поступить?
Спасибо!
1 ответ
На самом деле, что вызывает эту проблему является сочетание:
@XmlPath
аннотация наCustomer
боб иnamespacePrefixMapper
что вы вMoxyJsonConfig
что вызывает NullPointerException
во время (не) сортировки JSON. Это было исправлено в ночных версиях (2.5.1
а также 2.6.1
) МОКСИ. Вы можете скачать его со страницы Nightly Builds.
Если вы не хотите менять версию MOXy в данный момент, просто удалите эту строку
configuration.setNamespacePrefixMapper(namespacePrefixMapper);
от JsonMoxyConfigurationContextResolver
и ты должен быть в порядке.
Что касается проблемы с журналированием - мы знаем об этом, и все исправлено (должно быть решено в Jersey 2.3
).