我正在尝试发布List自定义对象。我在请求正文中的JSON是这样的:
List
{ "collection": [ { "name": "Test order1", "detail": "ahk ks" }, { "name": "Test order2", "detail": "Fisteku" } ] }
处理请求的服务器端代码:
import java.util.Collection; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @Path(value = "/rest/corder") public class COrderRestService { @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public Response postOrder(Collection<COrder> orders) { StringBuilder stringBuilder = new StringBuilder(); for (COrder c : orders) { stringBuilder.append(c.toString()); } System.out.println(stringBuilder); return Response.ok(stringBuilder, MediaType.APPLICATION_JSON).build(); } }
实体COrder:
COrder
import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class COrder { String name; String detail; @Override public String toString() { return "COrder [name=" + name + ", detail=" + detail + ", getClass()=" + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]"; } }
但是抛出一个异常:
SEVERE: Failed executing POST /rest/corder org.jboss.resteasy.spi.ReaderException: org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token at [Source: org.apache.catalina.connector.CoyoteInputStream@6de8c535; line: 1, column: 1] at org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:183) at org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:88) at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:111) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:280) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:234) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:221) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356) at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179) at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220) at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:724)
问题是JSON-默认情况下不能反序列化为,Collection因为它实际上不是JSON数组-看起来像这样:
Collection
[ { "name": "Test order1", "detail": "ahk ks" }, { "name": "Test order2", "detail": "Fisteku" } ]
由于你没有控制反序列化的确切过程(RestEasy确实如此)- 第一个选择是简单地将JSON作为a注入String,然后控制反序列化过程:
Collection<COrder> readValues = new ObjectMapper().readValue( jsonAsString, new TypeReference<Collection<COrder>>() { } );
你不必自己进行操作便会失去一些便利,但是你可以轻松地解决问题。
另一个选择 -如果不能更改JSON-将构造一个包装器以适合JSON输入的结构-并使用而不是Collection<COrder>。
Collection<COrder>
希望这可以帮助。