0
votes

Consider the following method:

@POST
@Path("/device")
@Consumes("application/json")
@Produces("application/json")
public String putDevice(String jsonObject, @Context HttpHeaders headers, Admin admin)
{
    ObjectMapper mapper = new ObjectMapper();

    try
    {
        return updateDevice(mapper.readTree(jsonObject), Utils.extractUserInfo(headers), admin.getServer(), admin.getPort());
    }
    catch (JsonProcessingException e)
    {
        return e.getMessage();
    }
    catch (IOException e)
    {
        return e.getMessage();
    }
}

When I call the WS from Postman, I get the following exception:

08-Feb-2019 14:23:44.138 GRAVE [http-nio-8080-exec-7] com.sun.jersey.spi.container.ContainerResponse.mapMappableContainerException The exception contained within MappableContainerException could not be mapped to a response, re-throwing to the HTTP container java.io.EOFException: No content to map to Object due to end of input at org.codehaus.jackson.map.ObjectMapper._initForReading(ObjectMapper.java:2766) at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2682) at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1308) at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:419) at com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy.readFrom(JacksonProviderProxy.java:139) at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:490) 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:86) 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$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:183) 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:302) 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:1542) at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1473) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419) at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409) at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558) at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733) at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748)

It's maybe important to mention that the exception disappears when I remove the parameter jsonObject and edit the method like this:

@POST
@Path("/device")
@Consumes("application/json")
@Produces("application/json")
public Response putDevice(@Context HttpHeaders headers, Admin admin)
{
    String output = admin.toString();
    return Response.status(200).entity(output).build();
}

Any suggestions would be much appreciated.

1
Try to add the @RequestBody anotation : putDevice(@RequestBody String jsonObject,.. .Arnaud
Thank you for your answer. However, I'm not using spring here. Is there an alternative for that annotation?Jesse James
Apparently, "The only parameter without annotation will be a container for request body" , see here stackoverflow.com/questions/41157949/… . You can't pass several object this way, there is only one request body.Arnaud
The link you posted gave me a clue to resolve the problem. Thank youJesse James

1 Answers

1
votes

Thanks to the link posted by Arnaud, I learned that you can only have one parameter without annotation, and that one will be processed as the request body. So I made the necessary changes, and here's how the method looks now:

@POST
@Path("/device")
@Consumes("application/json")
@Produces("application/json")
public String putDevice(String jsonString, @Context HttpHeaders headers)
{
    ObjectMapper mapper = new ObjectMapper();
    try
    {
    JSONObject jsonObject = new JSONObject(jsonString);
    return updateDevice(mapper.readTree(jsonString),
                        Utils.extractUserInfo(headers),
                        jsonObject.getString("server"),
                        jsonObject.getInt("port"));
}
    catch (JSONException e)
    {
        return e.getMessage();
    }
    catch (JsonProcessingException e)
    {
        return e.getMessage();
    }
    catch (IOException e)
    {
        return e.getMessage();
    }
}

I hope it'll help somebody else with the same problem one day.