ClientRequest,如何正确地将POJO序列化为json数据? 找不到内容类型application / json类型的writer:

对于REST服务(RESTeasy),我创建了JUnit测试用例,例如:

@Test public void a100_insertAddressTest() throws Exception { Address addr = new Address(1, "testStreet", "1", (short) 1234, "testCity"); ClientRequest request = new ClientRequest(BASE_URL + "customerID/{id}", sslExecutor_schusb); request.body(MediaType.APPLICATION_XML, addr).pathParameter( "id", 1); ClientResponse response = request.post(String.class); Assert.assertEquals(201, response.getStatus()); response.releaseConnection(); request.clear(); } 

如果我将请求正文的媒体类型更改为“application / json”,则测试用例将失败并显示错误:

 java.lang.RuntimeException: could not find writer for content-type application/json type: at.fhj.ase.dao.data.Address at org.jboss.resteasy.client.ClientRequest.writeRequestBody(ClientRequest.java:469) at org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor.loadHttpMethod(ApacheHttpClient4Executor.java:221) at org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor.execute(ApacheHttpClient4Executor.java:107) at org.jboss.resteasy.core.interception.ClientExecutionContextImpl.proceed(ClientExecutionContextImpl.java:39) at org.jboss.resteasy.plugins.interceptors.encoding.AcceptEncodingGZIPInterceptor.execute(AcceptEncodingGZIPInterceptor.java:40) at org.jboss.resteasy.core.interception.ClientExecutionContextImpl.proceed(ClientExecutionContextImpl.java:45) at org.jboss.resteasy.client.ClientRequest.execute(ClientRequest.java:443) at org.jboss.resteasy.client.ClientRequest.httpMethod(ClientRequest.java:674) at org.jboss.resteasy.client.ClientRequest.post(ClientRequest.java:565) at org.jboss.resteasy.client.ClientRequest.post(ClientRequest.java:570) at at.fhj.ase.business.ServiceAddressImplTest.a100_insertAddressTest(ServiceAddressImplTest.java:59) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168) at org.junit.rules.RunRules.evaluate(RunRules.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

因此,我创建了一个MessageBodyWriter ,如果我使用firefox插件RESTClient执行POST请求,它可以正常工作:

 @Provider @Produces(MediaType.APPLICATION_JSON) public class JsonMsbWriter implements MessageBodyWriter
{ @Override public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { if(type == Address.class){ return true; } return false; } @Override public long getSize(Address t, Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { return -1; } @Override public void writeTo(Address t, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { ObjectMapper m = new ObjectMapper(); m.writeValue(entityStream, t); } }

并将JUnit测试用例更新为:

 @Test public void a100_insertAddressTest() throws Exception { Address addr = new Address(1, "testStreet", "1", (short) 1234, "testCity"); ResteasyProviderFactory fact = ResteasyProviderFactory.getInstance(); fact.addMessageBodyWriter(JsonMsbWriter.class); ClientRequest request = new ClientRequest(BASE_URL + "customerID/{id}", sslExecutor_schusb); request.body(MediaType.APPLICATION_JSON, addr).pathParameter("id", 1); ClientResponse response = request.post(String.class); Assert.assertEquals(201, response.getStatus()); response.releaseConnection(); request.clear(); } 

但现在我收到了错误:

 java.lang.VerifyError: (class: org/codehaus/jackson/map/ObjectMapper, method: writeValueAsBytes signature: (Ljava/lang/Object;)[B) Incompatible argument to function at at.fhj.ase.xmlvalidation.msbreader.JsonMsbWriter.writeTo(JsonMsbWriter.java:46) at at.fhj.ase.xmlvalidation.msbreader.JsonMsbWriter.writeTo(JsonMsbWriter.java:1) at org.jboss.resteasy.core.interception.MessageBodyWriterContextImpl.proceed(MessageBodyWriterContextImpl.java:117) at org.jboss.resteasy.plugins.interceptors.encoding.GZIPEncodingInterceptor.write(GZIPEncodingInterceptor.java:100) at org.jboss.resteasy.core.interception.MessageBodyWriterContextImpl.proceed(MessageBodyWriterContextImpl.java:123) at org.jboss.resteasy.client.ClientRequest.writeRequestBody(ClientRequest.java:472) at org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor.loadHttpMethod(ApacheHttpClient4Executor.java:221) at org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor.execute(ApacheHttpClient4Executor.java:107) at org.jboss.resteasy.core.interception.ClientExecutionContextImpl.proceed(ClientExecutionContextImpl.java:39) at org.jboss.resteasy.plugins.interceptors.encoding.AcceptEncodingGZIPInterceptor.execute(AcceptEncodingGZIPInterceptor.java:40) at org.jboss.resteasy.core.interception.ClientExecutionContextImpl.proceed(ClientExecutionContextImpl.java:45) at org.jboss.resteasy.client.ClientRequest.execute(ClientRequest.java:443) at org.jboss.resteasy.client.ClientRequest.httpMethod(ClientRequest.java:674) at org.jboss.resteasy.client.ClientRequest.post(ClientRequest.java:565) at org.jboss.resteasy.client.ClientRequest.post(ClientRequest.java:570) at at.fhj.ase.business.ServiceAddressImplTest.a100_insertAddressTest(ServiceAddressImplTest.java:65) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168) at org.junit.rules.RunRules.evaluate(RunRules.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 
  1. 我如何为json附上这样的作家?
  2. 为什么它适用于内容类型application/xml开箱即用?

对于GET请求和application/json存在同样的问题,但是对于读者而不是编写者。

问题解决了,遗憾的是我还没有将所有必要的第三方库包含在项目构建路径中。 最后我添加了以下jar子:

  1. jackson核心ASL-1.6.3.jar
  2. jacksonJAXRS-1.6.3.jar
  3. jackson映射器-ASL-1.6.3.jar
  4. jackson-XC-1.6.3.jar
  5. RestEasy的jackson提供商,2.2.1.GA.jar

这个例子将Maven的优势带到了前面。 使用Maven,只需要一个条目来实现这些依赖关系。

  org.jboss.resteasy resteasy-jackson-provider 2.2.1.GA