2014-07-09 11 views
6

Il mio endpoint non può dare un senso al JSON in arrivo.Can not Deserialize JSON in Java Servlet

Ecco il punto finale:

sto postando JSON contenente la chiave/valore per "piattaforma" usando Postino, con l'intestazione: Content-Type come application/json

ma ottengo questa eccezione: com.owlike.genson.JsonBindingException: Could not deserialize to type class org.json.JSONObject

Sembra che il problema ha a che fare con: Illegal character at row 0 and column 1 expected { but read '-' !

ma sono m abbastanza sicuro postino dovrebbe essere l'invio di JSON valido ...

Ecco più del stacktrace:

09-Jul-2014 10:30:00.017 SEVERE [http-nio-8080-exec-4] com.sun.jersey.spi.container.ContainerResponse.logException Mapped exception to response: 500 (Internal Server Error) 
javax.ws.rs.WebApplicationException: com.owlike.genson.JsonBindingException: Could not deserialize to type class org.json.JSONObject 
    at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:127) 
    at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:474) 
    at com.sun.jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider$EntityInjectable.getValue(EntityParamDispatchProvider.java:123) 
    at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46) 
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153) 
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:203) 
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) 
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288) 
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) 
    at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) 
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) 
    at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349) 
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339) 
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) 
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537) 
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:725) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:526) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:655) 
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1566) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1523) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:744) 
Caused by: com.owlike.genson.JsonBindingException: Could not deserialize to type class org.json.JSONObject 
    at com.owlike.genson.Genson.deserialize(Genson.java:391) 
    at com.owlike.genson.ext.jaxrs.GensonJsonConverter.readFrom(GensonJsonConverter.java:125) 
    ... 41 more 
Caused by: com.owlike.genson.stream.JsonStreamException: Illegal character at row 0 and column 1 expected { but read '-' ! 
    at com.owlike.genson.stream.JsonReader.newWrongTokenException(JsonReader.java:949) 
    at com.owlike.genson.stream.JsonReader.begin(JsonReader.java:425) 
    at com.owlike.genson.stream.JsonReader.beginObject(JsonReader.java:157) 
    at com.owlike.genson.reflect.BeanDescriptor.deserialize(BeanDescriptor.java:101) 
    at com.owlike.genson.reflect.BeanDescriptor.deserialize(BeanDescriptor.java:90) 
    at com.owlike.genson.convert.BeanViewConverter.deserialize(BeanViewConverter.java:102) 
    at com.owlike.genson.convert.NullConverter$NullConverterWrapper.deserialize(NullConverter.java:56) 
    at com.owlike.genson.Genson.deserialize(Genson.java:389) 
    ... 42 more 
+3

Puoi controllare con http://www.telerik.com/fiddler cosa stai postando e aggiornare la tua domanda con i risultati. – Andreas

+0

Sì, si prega di intercettare e/o registrare la richiesta e trovare il contenuto del proprio oggetto JSON di richiesta http per consentirne l'ulteriore analisi. Se utilizzi Chrome o Firefox, dovresti riuscire a farlo utilizzando rispettivamente gli strumenti di sviluppo o Firebug. –

risposta

3

Questa potrebbe non essere una soluzione ideale, ma penso che potrebbe funzionare.

Speriamo di avere già la dipendenza di Jackson JSON ...

si può trovare qui: http://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core

vorrei provare il seguente codice:

@POST 
@Path("/{department}/{team}") 
@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.APPLICATION_JSON) 
public Response handleJSON(String json, @PathParam("department") String department,  @PathParam("team") String team){ 

    ObjectMapper mapper = new ObjectMapper(); 
    JsonNode node = mapper.readValue(json, JsonNode.class); 

    MyObj myObj = new MyObj(); 

    myObj.setDepartment(department); 
    myObj.setTeam(team); 

    if (node.get("platform") != null) { 
     myObj.setPlatform(node.get("platform").textValue()); 
    } 

    saveObj(myObj); 

    return Response.ok(true).build(); 

} 

noti che chiedo il vostro WS Framework mi ha appena passato il JSON come una String e me ne sono occupato da solo. Forse non è l'ideale, ma dovrebbe funzionare.

Cheers!

+0

Ho appena letto che stai usando Gensen, puoi aggiornare il codice per usare Gensen, ma posso vedere che probabilmente stai cercando un'integrazione più stretta con il tuo framework WS. In ogni caso, buona fortuna! – g00dnatur3

+0

ObjectMapper è thread-safe e dovrebbe essere costruito solo una volta ... volevo solo indicarlo – g00dnatur3

3

Non so che JSON Serializer si sta utilizzando, ma molto probabilmente questa sarà Jettison o Jackson. Per quanto ne so, non supportano direttamente la conversione di un'istanza di org.json.JSONObject. Il modo più comune è quello di usare semplicemente Java Beans personalizzato:

public class Foo implements Serializable { 

    private String platform; 

    // getters + setters 

} 

@POST 
@Path("/{department}/{team}") 
@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.APPLICATION_JSON) 
public Response handleJson(Foo foo, @PathParam("department") String department, @PathParam("team") String team) { 
    ... 
    myObj.setPlatform(foo.getPlatform()); 
    ... 
} 

Foo devono essere annotate con @XmlRootElement se si utilizza Jettison.

Se non si desidera creare un costume Bean per ogni Entità vi aspettate è possibile utilizzare Object, Map o String come parametro e serializzare da soli:

@POST 
@Path("/{department}/{team}") 
@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.APPLICATION_JSON) 
public Response handleJson(String json, @PathParam("department") String department, @PathParam("team") String team) { 
    ... 
    JSONObject jsonObject = new JSONObject(json); 
    myObj.setPlatform(json.optString("platform")); 
    ... 
} 

ultima soluzione è l'attuazione di un MessageBodyReader che gestisce JSONObject. Semplice esempio:

@Provider 
public class JsonObjectReader implements MessageBodyReader<JSONObject> { 

    @Override 
    public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { 
     return type == JSONObject.class && MediaType.APPLICATION_JSON_TYPE.equals(mediaType); 
    } 

    @Override 
    public JSONObject readFrom(Class<JSONObject> type, Type genericType, 
      Annotation[] annotations, MediaType mediaType, 
      MultivaluedMap<String, String> httpHeaders, InputStream entityStream) 
      throws IOException, WebApplicationException { 
     return new JSONObject(IOUtils.toString(entityStream)); 
    } 

} 
+0

Sto usando Genson. –

+0

Almeno i primi due esempi funzionano anche con Genson. – lefloh