[SPRING] START_OBJECT 토큰에서 java.util.ArrayList의 인스턴스를 deserialize 할 수 없습니다.
SPRINGSTART_OBJECT 토큰에서 java.util.ArrayList의 인스턴스를 deserialize 할 수 없습니다.
사용자 지정 개체 목록을 게시하려고합니다. 요청 본문의 JSON은 다음과 같습니다.
{
"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 :
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() + "]";
}
}
그러나 예외가 throw됩니다.
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)
해결법
-
==============================
1.문제는 JSON입니다. 기본적으로 JSON Array가 아니기 때문에 컬렉션으로 deserialize 할 수 없습니다.
문제는 JSON입니다. 기본적으로 JSON Array가 아니기 때문에 컬렉션으로 deserialize 할 수 없습니다.
[ { "name": "Test order1", "detail": "ahk ks" }, { "name": "Test order2", "detail": "Fisteku" } ]
deserialization의 정확한 프로세스 (RestEasy는 않습니다)를 제어하지 않기 때문에 첫 번째 옵션은 단순히 JSON을 String으로 삽입 한 다음 deserialization 프로세스를 제어하는 것입니다.
Collection<COrder> readValues = new ObjectMapper().readValue(jsonAsString, new TypeReference<Collection<COrder>>() { });
스스로 할 필요가없는 편리함을 잃어 버릴 지 모르지만 문제를 쉽게 해결할 수 있습니다.
또 다른 옵션 - JSON을 변경할 수 없다면 JSON 입력 구조에 맞는 래퍼를 생성하여 Collection
대신 사용할 수 있습니다. 희망이 도움이됩니다.
-
==============================
2.JSON 문서 대신 아래와 같이 ObjectMapper 객체를 업데이트 할 수 있습니다.
JSON 문서 대신 아래와 같이 ObjectMapper 객체를 업데이트 할 수 있습니다.
ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
-
==============================
3.이것은 작동 할 것이다 :
이것은 작동 할 것이다 :
이 문제는 JsonNode가 아닌 JsonArray로 단일 요소가있는 목록을 읽거나 그 반대의 경우도 발생할 수 있습니다.
반환 된 목록에 단일 요소가 포함되어 있는지 (json이이 {...}처럼 보일 때) 또는 여러 요소가 있는지 (& json은 [{...}, {...와 같이 보입니다. }])) - 런타임에 요소의 유형을 확인해야합니다.
다음과 같이 표시되어야합니다.
(참고 :이 코드 샘플에서는 com.fasterxml.jackson을 사용하고 있습니다)
String jsonStr = response.readEntity(String.class); ObjectMapper mapper = new ObjectMapper(); JsonNode rootNode = mapper.readTree(jsonStr); // Start by checking if this is a list -> the order is important here: if (rootNode instanceof ArrayNode) { // Read the json as a list: myObjClass[] objects = mapper.readValue(rootNode.toString(), myObjClass[].class); ... } else if (rootNode instanceof JsonNode) { // Read the json as a single object: myObjClass object = mapper.readValue(rootNode.toString(), myObjClass.class); ... } else { ... }
-
==============================
4.스프링 프레임 워크를 사용하여 만든 REST API에서이 문제가 발생했습니다. @ResponseBody 주석을 추가하여 (응답 JSON으로 만들기 위해)이를 해결했습니다.
스프링 프레임 워크를 사용하여 만든 REST API에서이 문제가 발생했습니다. @ResponseBody 주석을 추가하여 (응답 JSON으로 만들기 위해)이를 해결했습니다.
from https://stackoverflow.com/questions/20837856/can-not-deserialize-instance-of-java-util-arraylist-out-of-start-object-token by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 부트를 가져 와서 데이터베이스 스키마를 자동으로 만들 수 없습니다. (0) | 2018.12.08 |
---|---|
[SPRING] 스프링 부트 애플리케이션을 프로그래밍 방식으로 종료 (0) | 2018.12.08 |
[SPRING] AngularJS html5Mode로 봄 부팅 (0) | 2018.12.08 |
[SPRING] 일치하는 와일드 카드는 엄격하지만 요소의 컨텍스트에 대한 선언을 찾을 수 없습니다. component-scan (0) | 2018.12.08 |
[SPRING] 스프링 MVC 컨트롤러에 대한 GET 요청에서 날짜 매개 변수를 수락하는 방법? (0) | 2018.12.08 |