2012-12-04 38 views
2

我已經使用jersey在java中編寫了一個REST API。當我使用XML請求時,一切正常,但是當我使用JSON請求時,我總是得到一個JsonMappingException。Java JsonMappingException錯誤

使用來自xsd文件的Jaxb生成對象。由於XML請求正在工作,我假定這些生成的對象是正確的。

誰能告訴我我失蹤了什麼?

(在底部,你可以找到錯誤信息時,WS,對象&的XSD的一個例子)

在此先感謝。

錯誤:

[#|2012-12-04T18:55:56.599+0100|WARNING|glassfish3.1.2|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=29;_ThreadName=Thread-2;|StandardWrapperValve[ServletAdaptor]: PWC1406: Servlet.service() for servlet ServletAdaptor threw exception 
org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class javax.xml.bind.JAXBElement<be.api.schema.sensorrequest.SensorCreateRequest>]: can not instantiate from JSON object (need to add/enable type information?) 
at [Source: [email protected]; line: 2, column: 1] 
     at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163) 
     at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObjectUsingNonDefault(BeanDeserializer.java:740) 
     at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:683) 
     at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580) 
     at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2695) 
     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: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$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:288) 
     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:708) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:770) 
     at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 
     at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 
     at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) 
     at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) 
     at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) 
     at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 
     at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) 
     at com.sun.grizzly.http.ajp.AjpProcessorTask.invokeAdapter(AjpProcessorTask.java:135) 
     at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757) 
     at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056) 
     at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229) 
     at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 
     at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 
     at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 
     at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 
     at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 
     at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 
     at com.sun.grizzly.ContextTask.run(ContextTask.java:71) 
     at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) 
     at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) 
     at java.lang.Thread.run(Thread.java:662) 
|#] 

的WS實現:

@POST 
    @Consumes(
    { 
     MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON 
    }) 
    @Produces(
    { 
     MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON 
    }) 
    @Validation(requestObject = SensorCreateRequest.class, xsd = "SensorRequest.xsd") 
    public SensorCreateResponse post(@TypeHint(SensorCreateRequest.class) JAXBElement<SensorCreateRequest> JAXBSensorCreateRequest, 
            @HeaderParam(value = "client") String clientName, 
            @HeaderParam(value = "session") String sessionToken) throws WebApplicationException 
    { 

    } 

請求對象(SensorCreateRequest)

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "SensorCreateRequestType", propOrder = { 

}) 
@XmlRootElement(name = "sensorCreateRequest") 
public class SensorCreateRequest implements Serializable, Equals, HashCode, ToString 
{ 

    @XmlElement(namespace = "http://www.api.be/schema/Sensor", required = true) 
    protected Sensors sensors; 

    /** 
    * Default no-arg constructor 
    * 
    */ 
    public SensorCreateRequest() { 
     super(); 
    } 

    /** 
    * Fully-initialising value constructor 
    * 
    */ 
    public SensorCreateRequest(final Sensors sensors) { 
     this.sensors = sensors; 
    } 

    //Getters, Setters, toString, hash & equals 

} 

的傳感器對象:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "SensorsType", propOrder = { 
    "sensors" 
}) 
@XmlRootElement(name = "sensors") 
public class Sensors implements Serializable, Equals, HashCode, ToString 
{ 

    @XmlElement(name = "sensor") 
    protected List<Sensor> sensors; 

    /** 
    * Default no-arg constructor 
    * 
    */ 
    public Sensors() { 
     super(); 
    } 

    /** 
    * Fully-initialising value constructor 
    * 
    */ 
    public Sensors(final List<Sensor> sensors) { 
     this.sensors = sensors; 
    } 

    //Getters, Setters, toString, hash & equals 

} 

的傳感器對象:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "SensorType", propOrder = { 
    "sensorId", 
    "name", 
    "token", 
    "groups", 
    "locations", 
    "dataProfile", 
    "status", 
    "first", 
    "last", 
    "lastValue", 
    "longName", 
    "circles" 
}) 
@XmlRootElement(name = "sensor") 
public class Sensor implements Serializable, Equals, HashCode, ToString 
{ 

    protected int sensorId; 
    @XmlElement(required = true) 
    protected String name; 

    /** 
    * Default no-arg constructor 
    * 
    */ 
    public Sensor() { 
     super(); 
    } 

    /** 
    * Fully-initialising value constructor 
    * 
    */ 
    public Sensor(final int sensorId, final String name) { 
     this.sensorId = sensorId; 
     this.name = name; 
    } 

    //Getters, Setters, toString, hash & equals 

} 

的SensorRequest XSD:

<?xml version="1.0" encoding="UTF-8"?> 

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
     targetNamespace="http://www.api.be/schema/SensorRequest" 
     xmlns:tns="http://www.api.be/schema/SensorRequest" 
     xmlns:s="http://www.api.be/schema/Sensor" 
     elementFormDefault="qualified"> 

    <xsd:import namespace="http://www.api.be/schema/Sensor" schemaLocation="Sensor.xsd"/> 

    <xsd:element name="sensorCreateRequest" type="tns:SensorCreateRequestType"/> 

    <xsd:complexType name="SensorCreateRequestType"> 
     <xsd:all> 
      <xsd:element ref="s:sensors" minOccurs="1" maxOccurs="1" /> 
     </xsd:all> 
    </xsd:complexType> 

</xsd:schema> 

的傳感器的xsd:

<?xml version="1.0" encoding="UTF-8"?> 

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      targetNamespace="http://www.api.be/schema/Sensor" 
      xmlns:tns="http://www.api.be/schema/Sensor" 
      elementFormDefault="qualified"> 

    <!-- Sensor --> 
    <xsd:element name="sensors" type="tns:SensorsType"/> 

    <xsd:complexType name="SensorsType"> 
     <xsd:sequence> 
      <xsd:element name="sensor" type="tns:SensorType" minOccurs="0" maxOccurs="unbounded"/> 
     </xsd:sequence> 
    </xsd:complexType> 

    <xsd:element name="sensor" type="tns:SensorType" /> 

    <!-- Sensors --> 
    <xsd:complexType name="SensorType"> 
     <xsd:sequence> 
      <xsd:element name="sensorId" type="xsd:int" minOccurs="1" maxOccurs="1"/> 
      <xsd:element name="name" type="xsd:string" minOccurs="1" maxOccurs="1"/> 
     </xsd:sequence> 
    </xsd:complexType> 
</xsd:schema> 
+0

我發現,當我從WS刪除JAXBElement的類型,它的工作原理。然後JSON和XML請求被正確解析。有沒有辦法讓JSON解析器使用JAXBElement? – ToHe

回答

1

注:我是EclipseLink JAXB (MOXy)鉛和成員JAXB (JSR-222)專家組。 JAXB(JSR-222)規範沒有提到有關JSON綁定的任何內容。 JAX-RS提供者利用的幾個JSON綁定實現能夠從JAXB註釋中派生JSON表示。在您的環境中,您正在使用Jackson。 Jackson支持JAXB元數據的一個子集,目前不支持JAXBElement類。從傑克遜鉛參見下面的回答:

的EclipseLink JAXB(莫西)提供了支持所有JAXB構建在我們的JSON結合的實現,它可能是一個更適合您使用情況:

下面是一些正式開通了一個鏈接升州的例子,充分利用莫西作爲JSON提供: