无法从 START_OBJECT 令牌反序列化 java.util.ArrayList 的实例 [英] Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

查看:110
本文介绍了无法从 START_OBJECT 令牌反序列化 java.util.ArrayList 的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试发布自定义对象的 List.我在请求正文中的 JSON 是这样的:

<代码>{收藏": [{"name": "测试订单1",详细信息":ahk ks"},{"name": "测试订单2",细节":Fisteku"}]}

处理请求的服务器端代码:

import java.util.Collection;导入 javax.ws.rs.Consumes;导入 javax.ws.rs.POST;导入 javax.ws.rs.Path;导入 javax.ws.rs.Produces;导入 javax.ws.rs.core.MediaType;导入 javax.ws.rs.core.Response;@Path(value = "/rest/corder")公共类 COrderRestService {@邮政@Produces(MediaType.APPLICATION_JSON)@Consumes(MediaType.APPLICATION_JSON)公共响应 postOrder(Collection orders) {StringBuilder stringBuilder = new StringBuilder();for (COrder c : 订单) {stringBuilder.append(c.toString());}System.out.println(stringBuilder);返回 Response.ok(stringBuilder, MediaType.APPLICATION_JSON).build();}}

实体COrder:

import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement公共类代码{字符串名称;字符串细节;@覆盖公共字符串 toString() {return "COrder [name=" + name + ", detail=" + detail+ ", getClass()=" + getClass() + ", hashCode()=" + hashCode()+ ", toString()=" + super.toString() + "]";}}

但是抛出异常:

严重:执行 POST/rest/corder 失败org.jboss.resteasy.spi.ReaderException: org.codehaus.jackson.map.JsonMappingException: 无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList 的实例在 [来源:org.apache.catalina.connector.CoyoteInputStream@6de8c535;行:1,列:1]在 org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:183)在 org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:88)在 org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:111)在 org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:280)在 org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:234)在 org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:221)在 org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356)在 org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179)在 org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220)在 org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)在 org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)在 javax.servlet.http.HttpServlet.service(HttpServlet.java:728)在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)在 org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)在 org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)在 org.apache.tomcat.util.net.JioEndpoint$SocketProcessor.run(JioEndpoint.java:312)在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)在 java.lang.Thread.run(Thread.java:724)

解决方案

问题在于 JSON - 默认情况下,这不能反序列化为 Collection 因为它实际上不是 JSON 数组 - 即看起来像这样:

<预><代码>[{"name": "测试订单1",详细信息":ahk ks"},{"name": "测试订单2",细节":Fisteku"}]

由于您无法控制反序列化的确切过程(RestEasy 可以) - 第一个选项 将简单地将 JSON 作为 String 注入,然后进行控制反序列化过程:

CollectionreadValues = new ObjectMapper().readValue(jsonAsString, new TypeReference>() { });

您会失去一些不必自己做的便利,但您可以轻松解决问题.

另一种选择 - 如果您无法更改 JSON - 将构建一个包装器以适应您的 JSON 输入的结构 - 并使用它代替 Collection.

希望这会有所帮助.

I'm trying to POST a List of custom objects. My JSON in request body is this:

{
    "collection": [
        {
            "name": "Test order1",
            "detail": "ahk ks"
        },
        {
            "name": "Test order2",
            "detail": "Fisteku"
        }
    ]
}

Server side code that handles the request:

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();
    }
}

Entity 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() + "]";
    }
}

But an exception is thrown:

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)

解决方案

The problem is the JSON - this cannot, by default, be deserialized into a Collection because it's not actually a JSON Array - that would look like this:

[
    {
        "name": "Test order1",
        "detail": "ahk ks"
    },
    {
        "name": "Test order2",
        "detail": "Fisteku"
    }
]

Since you're not controlling the exact process of deserialization (RestEasy does) - a first option would be to simply inject the JSON as a String and then take control of the deserialization process:

Collection<COrder> readValues = new ObjectMapper().readValue(
    jsonAsString, new TypeReference<Collection<COrder>>() { }
);

You would loose a bit of the convenience of not having to do that yourself, but you would easily sort out the problem.

Another option - if you cannot change the JSON - would be to construct a wrapper to fit the structure of your JSON input - and use that instead of Collection<COrder>.

Hope this helps.

这篇关于无法从 START_OBJECT 令牌反序列化 java.util.ArrayList 的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆