我已经被这个问题困扰了好几天,现在正在寻找一些指导来帮助解决这个问题。我在Metro下的jax-ws方面有相当丰富的经验,但这是我第一次与Jersey一起使用jax-rs。为了简化移动部件,我以球衣示例moxy代码为起点。
我修改了示例项目以接受XML和JSON。我原以为这很简单,但我似乎错过了一些东西,因为这是一次痛苦的经历。当我请求"application/xml"时,代码运行时没有问题,GET将适用于"application/json",但当我尝试用json执行PUT时,服务器返回500状态代码。我可以看到PUT请求中发送了JSON,但服务器在接受JSON时似乎遇到了问题。
这是修改后的CustomerResource.java文件段。我所做的只是将MediaType.APPLICATION_JSON参数添加到Produces和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媒体类型:
@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类和createApp()方法中的registerInstances()调用。(注意,去掉这个不会改变结果)。
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;
}
}
以下是显示"application/xml"PUT成功的日志段,状态为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响应中没有返回任何信息。有什么方法可以获得额外的异常详细信息吗?
对如何进行有什么建议吗?
谢谢!
实际上,导致此问题的原因是:
Customer
bean上的@XmlPath
注释,以及- 您正在设置为
MoxyJsonConfig
的namespacePrefixMapper
这在(取消)编组JSON期间导致CCD_ 5。这已在MOXy的夜间版本(2.5.1
和2.6.1
)中得到修复。你可以从Nightly Builds页面下载。
如果你现在不想更改MOXy的版本,只需删除这行
configuration.setNamespacePrefixMapper(namespacePrefixMapper);
来自JsonMoxyConfigurationContextResolver
,你应该没事。
关于日志记录问题,我们知道它,它已经修复(应该在Jersey 2.3
中解决)。