PeakGen PeakGen - 5 months ago 235
Java Question

Java REST API: Can not deserialize instance of Object out of START_ARRAY token

I have a REST API written using Java and Jersey. Below is the related code of the WEB API.

@GET
@Path("/getAllPhase1")
@Produces(MediaType.APPLICATION_JSON)
public List<Phase1Bean> getAllPhase1()
{
Phase1Interface phase1Interface = new Phase1Impl();
List<Phase1Bean> allPhase1 = phase1Interface.getAllPhase1();
return allPhase1;
}


In my web application's REST client, I wrote the below code.

Client client = ClientBuilder.newClient();

client.target("http://localhost:8080/xxx/rest")
.path("phase1/getAllPhase1")
.request(MediaType.APPLICATION_JSON)
.get(Phase1Bean.class);


Unfortunatly this generates the below error

Exception in thread "main" javax.ws.rs.client.ResponseProcessingException: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of bean.Phase1Bean out of START_ARRAY token
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@2fb3536e; line: 1, column: 1]
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:806)
at org.glassfish.jersey.client.JerseyInvocation.access$700(JerseyInvocation.java:92)
at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:700)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:696)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:420)
at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:316)
at JerseyClientGet.main(JerseyClientGet.java:32)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of bean.Phase1Bean out of START_ARRAY token
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@2fb3536e; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:691)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:685)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromArray(BeanDeserializerBase.java:1215)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:126)
at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1233)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:677)
at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:777)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:256)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:235)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:808)
at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:803)
... 10 more
Java Result: 1


How can I solve this issue?

Answer

Your GET method is returning a List, rather than a single Phase1Bean object - hence the "START_ARRAY" token mentioned in the error message. You can change your client .get() method to receive a List, and then extract the Phase1Bean items from there.

client.target("http://localhost:8080/xxx/rest")
        .path("phase1/getAllPhase1")
        .request(MediaType.APPLICATION_JSON)
        .get(new GenericType<List<Phase1Bean>>(){});

An alternative would be to wrap your list in another object (Phase1BeanResponse, for example), containing the list and possibly other metadata related to the items.

Comments