Java MOXy JAXB异常,带有;“类型”;作为子类鉴别器处理的字段

Java MOXy JAXB异常,带有;“类型”;作为子类鉴别器处理的字段,java,json,jaxb,moxy,Java,Json,Jaxb,Moxy,我正在使用Jersey REST客户端api编写一个简单的地理编码应用程序,该应用程序使用OpenStreetMap/Mapquest REST服务。调用返回类似以下内容的JSON响应: [ { "place_id":"249137377", "licence":"Data \u00a9 OpenStreetMap contributors, ODbL 1.0. http:\/\/www.openstreetmap.org\/copyright", "boundingbox":["3

我正在使用Jersey REST客户端api编写一个简单的地理编码应用程序,该应用程序使用OpenStreetMap/Mapquest REST服务。调用返回类似以下内容的JSON响应:

[ {
  "place_id":"249137377",
  "licence":"Data \u00a9 OpenStreetMap contributors, ODbL 1.0. http:\/\/www.openstreetmap.org\/copyright",
  "boundingbox":["32.834854904644","32.834954904644","-79.243545952863","-79.243445952863"],
  "lat":"32.8349049046436",
  "lon":"-79.2434959528633",
  "display_name":"9000, Maple Avenue, Bedford, Trimble County, Kentucky, 40006, United States of America",
  "class":"place",
  "type":"house",
  "importance":0.521
} ]
如您所见,它包含一个名为
type
的字段。在解组此JSON响应时,引发以下异常:

Caused by: Exception [EclipseLink-43] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5):     org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class for indicator field value [house] of type [class java.lang.String].
Descriptor: XMLDescriptor(com.edc.c2c.geospatial.nominatim.v1.model.impl.NominatimResponse --> [])
    at org.eclipse.persistence.exceptions.DescriptorException.missingClassForIndicatorFieldValue(DescriptorException.java:940)
    at org.eclipse.persistence.internal.oxm.QNameInheritancePolicy.classFromRow(QNameInheritancePolicy.java:266)
    at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.classFromRow(TreeObjectBuilder.java:182)
    at org.eclipse.persistence.internal.oxm.TreeObjectBuilder.classFromRow(TreeObjectBuilder.java:1)
    at org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.initializeRecord(UnmarshalRecordImpl.java:502)
    at org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.startElement(UnmarshalRecordImpl.java:740)
    at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parseRoot(JSONReader.java:177)
    at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parseRoot(JSONReader.java:195)
    at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:125)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:972)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:425)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:635)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:703)
    at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:655)
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:301)
    at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.readFrom(MOXyJsonProvider.java:597)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:188)
    at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:134)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:988)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:833)
    at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:768)
    at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:96)
    at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:761)
    ... 31 more
我推测发生错误是因为
type
被视为一种类鉴别器,
house
被解释为一个子类而不是一个简单的字符串

这是用于调用服务的代码:

public Coordinate lookup( StreetAddress a_StreetAddress )
{
    LatLongCoordinate result = null ;

    Client client = ClientBuilder.newClient() ;
    client.register( MoxyXmlFeature.class ) ;

    WebTarget target = client.target( this.getEndPointUrl() ) ;
    NominatimResponse response =
        target
            .queryParam( "q", a_StreetAddress.format() ) // Buildup GET request
            .queryParam( "format", "json" )
            .queryParam( "addressdetails", "0" )
            .queryParam( "limit", "1" )
            .request( MediaType.APPLICATION_JSON_TYPE )  // Only accept JSON back in response
            .buildGet()
            .invoke( NominatimResponse.class )
            ;

    if ( ( response != null ) && ( response.getLatitude() != null ) && ( response.getLongitude() != null ) ) {
        result = new LatLongCoordinate( response.getLatitude(), response.getLongitude() ) ;
    }

    return result ;
}
这是创建的
namitmResponse
类I,用于将响应解组为:

public class NominatimResponse extends AbstractGeospatialModelObject
{
    private static final long serialVersionUID = -7514888439468843335L ;

    @XmlElement( name = "place_id" ) 
    private String m_PlaceId = null ;
    @XmlElement( name = "license" ) 
    private String m_License = null ;
    @XmlElement( name = "osm_type" ) 
    private String m_OsmType = null ;
    @XmlElement( name = "osm_id" ) 
    private String m_OsmId = null ;
    @XmlElement( name = "bounding_box")
    private Double[] m_BoundingBox = null ;
    @XmlElement( name = "lat" ) 
    private Double m_Latitude = null ;
    @XmlElement( name = "lon" ) 
    private Double m_Longitude = null ;
    @XmlElement( name = "display_name" ) 
    private String m_DisplayName = null ;
    @XmlElement( name = "class" ) 
    private String m_Classifier = null ;
    @XmlElement( name = "type" )
    private String m_Type = null ;
    @XmlElement( name = "importance" ) 
    private Double m_Importance = null ;


    /**
     * @return the placeId
     */
    public String getPlaceId()
    {
    return this.m_PlaceId ;
    }
    /**
     * @param a_placeId the placeId to set
     */
    public void setPlaceId( String a_placeId )
    {
    this.m_PlaceId = a_placeId ;
    }
    /**
     * @return the license
     */
    public String getLicense()
    {
    return this.m_License ;
    }
    /**
     * @param a_license the license to set
     */
    public void setLicense( String a_license )
    {
    this.m_License = a_license ;
    }
    /**
     * @return the osmType
     */
    public String getOsmType()
    {
    return this.m_OsmType ;
    }
    /**
     * @param a_osmType the osmType to set
     */
    public void setOsmType( String a_osmType )
    {
    this.m_OsmType = a_osmType ;
    }
    /**
     * @return the osmId
     */
    public String getOsmId()
    {
    return this.m_OsmId ;
    }
    /**
     * @param a_osmId the osmId to set
     */
    public void setOsmId( String a_osmId )
    {
    this.m_OsmId = a_osmId ;
    }
    /**
     * @return the boundingBox
     */
    public Double[] getBoundingBox()
    {
    return this.m_BoundingBox ;
    }
    /**
     * @param a_boundingBox the boundingBox to set
     */
    public void setBoundingBox( Double[] a_boundingBox )
    {
    this.m_BoundingBox = a_boundingBox ;
    }
    /**
     * @return the latitude
     */
    public Double getLatitude()
    {
    return this.m_Latitude ;
    }
    /**
     * @param a_latitude the latitude to set
     */
    public void setLatitude( Double a_latitude )
    {
    this.m_Latitude = a_latitude ;
    }
    /**
     * @return the longitude
     */
    public Double getLongitude()
    {
    return this.m_Longitude ;
    }
    /**
     * @param a_longitude the longitude to set
     */
    public void setLongitude( Double a_longitude )
    {
    this.m_Longitude = a_longitude ;
    }
    /**
     * @return the displayName
     */
    public String getDisplayName()
    {
    return this.m_DisplayName ;
    }
    /**
     * @param a_displayName the displayName to set
     */
    public void setDisplayName( String a_displayName )
    {
    this.m_DisplayName = a_displayName ;
    }
    /**
     * @return the classifier
     */
    public String getClassifier()
    {
    return this.m_Classifier ;
    }
    /**
     * @param a_classifier the classifier to set
     */
    public void setClassifier( String a_classifier )
    {
    this.m_Classifier = a_classifier ;
    }
    /**
     * @return the type
     */
    public String getType()
    {
    return this.m_Type ;
    }
    /**
     * @param a_type the type to set
     */
    public void setType( String a_type )
    {
    this.m_Type = a_type ;
    }
    /**
     * @return the importance
     */
    public Double getImportance()
    {
    return this.m_Importance ;
    }
    /**
     * @param a_importance the importance to set
     */
    public void setImportance( Double a_importance )
    {
    this.m_Importance = a_importance ;
    }

}
有没有一种方法可以防止莫西像看上去那样对待
type
?似乎它需要与
@xmlscriminatornode
等相反


提前感谢您的帮助。

我遇到了同样的问题。我从莫西转到了杰克逊,因为杰克逊似乎处理得很好

只需更改构建脚本中的jersey media依赖项即可

// remove this
compile 'org.glassfish.jersey.media:jersey-media-moxy:2.13'

// add this
compile 'org.glassfish.jersey.media:jersey-media-json-jackson:2.13'

谢谢你的建议。我最终创建了一个替代解决方案(使用直接的JsonObject),并放弃了Moxy封送。下次,我会和杰克逊一起尝试。