使用Jersey通过REST发送字符串[]

使用Jersey通过REST发送字符串[],jersey,jackson,jax-rs,jboss7.x,Jersey,Jackson,Jax Rs,Jboss7.x,我正在尝试用Jersey实现REST Web服务。我使用JBossAS 7.1.1 Final作为我的Web服务器 每当我尝试使用字符串[]作为方法签名的一部分时,就会出现问题: @Override @POST @Path("/getVersion") public ControllerVersion getVersion(String deviceID, String[] macAddresses) { System.out.println("Received "+deviceID+"

我正在尝试用Jersey实现REST Web服务。我使用JBossAS 7.1.1 Final作为我的Web服务器

每当我尝试使用字符串[]作为方法签名的一部分时,就会出现问题:

@Override
@POST
@Path("/getVersion")
public ControllerVersion getVersion(String deviceID, String[] macAddresses)
{
    System.out.println("Received "+deviceID+", and macAddress[0] "+macAddresses[0]);
    return new ControllerVersion();
}
服务器端引发的异常如下所示:

15:15:09,487 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/DCPController2].[JerseyRest]] (http--0.0.0.0-8080-1) Servlet.service() for servlet JerseyRest threw exception: java.io.EOFException: No content to map to Object due to end of input
        at org.codehaus.jackson.map.ObjectMapper._initForReading(ObjectMapper.java:2775) [jackson-all-1.9.9.jar:1.9.9]
        at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2691) [jackson-all-1.9.9.jar:1.9.9]
        at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1315) [jackson-all-1.9.9.jar:1.9.9]
        at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:419) [jackson-all-1.9.9.jar:1.9.9]
        at com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy.readFrom(JacksonProviderProxy.java:139) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:488) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider$EntityInjectable.getValue(EntityParamDispatchProvider.java:123) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:183) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1511) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1442) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716) [jersey-bundle-1.17.1.jar:1.17.1]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
        at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
        at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_45]
通过将以下内容添加到我的web.xml中,我确保启用POJOMapping:

 <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
注意,我还从JBoss中的standalone.xml文件中禁用了jaxrs子系统

我尝试使用Jersey主要是因为我在使用CXF-RS和Jackson时遇到了问题。您可以查看我的其他帖子,了解以下URL的更多信息:

非常感谢你的帮助

更新: 我在客户端中使用Apache的HttpPost进行调用,并将请求参数如下所示:

15:15:09,487 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/DCPController2].[JerseyRest]] (http--0.0.0.0-8080-1) Servlet.service() for servlet JerseyRest threw exception: java.io.EOFException: No content to map to Object due to end of input
        at org.codehaus.jackson.map.ObjectMapper._initForReading(ObjectMapper.java:2775) [jackson-all-1.9.9.jar:1.9.9]
        at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2691) [jackson-all-1.9.9.jar:1.9.9]
        at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1315) [jackson-all-1.9.9.jar:1.9.9]
        at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:419) [jackson-all-1.9.9.jar:1.9.9]
        at com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy.readFrom(JacksonProviderProxy.java:139) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:488) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider$EntityInjectable.getValue(EntityParamDispatchProvider.java:123) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:183) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1511) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1442) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538) [jersey-bundle-1.17.1.jar:1.17.1]
        at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716) [jersey-bundle-1.17.1.jar:1.17.1]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
        at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
        at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_45]

StringEntity参数=新的StringEntity(“{\“deviceID\”:\“testDevice\”,\“macAddresses\”:[1,2,3]}”)

你使用@POST而不是@GET的原因是什么? 该调用似乎更适合GET,除非您将大量mac地址列表传递给该调用

如果可能的话,根据您的要求,使用以下方法应该是可行的:

@GET
@Path("device/{deviceId}/version")
public ControllerVersion getVersion(@PathParam("deviceId") String deviceId, @QueryParam("mac") List<String> macAddresses) {
   ...
}
您可以使用Apache的HttpGet实例调用它。Jersey将自动将重复键转换为字符串值列表

我也会避免在你的道路上使用动词。“device/{id}/version”或“/version/{id}”将更加RESTful。此外,如果返回json,请不要忘记添加@products(MediaType.APPLICATION\u json)

更新:我能够重现问题。并根据您的岗位要求,开展以下工作:

@POST
@Path("/version")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public ControllerVersion getVersion(Device device)
{
    System.out.println("Received "+device.getDeviceID()+", and macAddress[0] "+ device.getMacAddresses()[0]);
    return new ControllerVersion();
}
添加了POJO类:

public class Device
{
    @JsonProperty
    String deviceID;

    @JsonProperty
    String[] macAddresses;

    public String getDeviceID()
    {
        return deviceID;
    }

    public void setDeviceID(String deviceID)
    {
        this.deviceID = deviceID;
    }

    public String[] getMacAddresses()
    {
        return macAddresses;
    }

    public void setMacAddresses(String[] macAddresses)
    {
        this.macAddresses = macAddresses;
    }
}

我的第一个假设是,Jackson无法将您的请求映射到通用对象,因为它没有您在json中指定的属性,因此您的异常。一旦定义了映射到这些值的契约,就可以进行反序列化。

使用@POST而不是@GET的原因是什么? 该调用似乎更适合GET,除非您将大量mac地址列表传递给该调用

如果可能的话,根据您的要求,使用以下方法应该是可行的:

@GET
@Path("device/{deviceId}/version")
public ControllerVersion getVersion(@PathParam("deviceId") String deviceId, @QueryParam("mac") List<String> macAddresses) {
   ...
}
您可以使用Apache的HttpGet实例调用它。Jersey将自动将重复键转换为字符串值列表

我也会避免在你的道路上使用动词。“device/{id}/version”或“/version/{id}”将更加RESTful。此外,如果返回json,请不要忘记添加@products(MediaType.APPLICATION\u json)

更新:我能够重现问题。并根据您的岗位要求,开展以下工作:

@POST
@Path("/version")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public ControllerVersion getVersion(Device device)
{
    System.out.println("Received "+device.getDeviceID()+", and macAddress[0] "+ device.getMacAddresses()[0]);
    return new ControllerVersion();
}
添加了POJO类:

public class Device
{
    @JsonProperty
    String deviceID;

    @JsonProperty
    String[] macAddresses;

    public String getDeviceID()
    {
        return deviceID;
    }

    public void setDeviceID(String deviceID)
    {
        this.deviceID = deviceID;
    }

    public String[] getMacAddresses()
    {
        return macAddresses;
    }

    public void setMacAddresses(String[] macAddresses)
    {
        this.macAddresses = macAddresses;
    }
}

我的第一个假设是,Jackson无法将您的请求映射到通用对象,因为它没有您在json中指定的属性,因此您的异常。一旦定义了映射到值的契约,就可以进行反序列化。

您实际上在方法中发布了什么?JSON字符串?是的,我的客户端正在发送一个StringEntity,如下所示:StringEntity参数=新的StringEntity(“{\”deviceID\”:\“testDevice\”,“macAddresses\”:[1,2,3]}”);因此,我的JSon字符串如下所示:{“deviceID”:“testDevice”,“MacAddresss”:[1,2,3]}您在方法中实际发布了什么?JSON字符串?是的,我的客户端正在发送一个StringEntity,如下所示:StringEntity参数=新的StringEntity(“{\”deviceID\”:\“testDevice\”,“macAddresses\”:[1,2,3]}”);因此,我的JSon字符串如下所示:{“deviceID”:“testDevice”,“MacAddresss”:[1,2,3]}我对使用POST有严格的要求。我仍然不明白为什么会出现上述异常。我的客户是否应该将macAddresses数组作为单独的实体发送?Ryan,这肯定是问题所在。问题在于向web服务发送多个参数。如果我将所有参数都放在一个POJO类中,那么一切都会完美工作。然而,我采取了不同的方法。请检查我对这个问题的回答:我对使用这个职位有严格的要求。我仍然不明白为什么会出现上述异常。我的客户是否应该将macAddresses数组作为单独的实体发送?Ryan,这肯定是问题所在。问题在于向web服务发送多个参数。如果我将所有参数都放在一个POJO类中,那么一切都会完美工作。然而,我采取了不同的方法。请检查我对这个问题的回答: