2014-12-04 46 views
1

我正在編寫一個簡單的地理編碼應用程序,使用Jersey REST客戶端API,使用OpenStreetMap/Mapquest Nominatim REST服務。該調用返回一個類似的JSON響應:MOXY JAXB異常與「類型」字段處理爲子類辨別器

[ { 
    "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 ; 
} 

這是NominatimResponse類我創建解組應答到:

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看起來是這樣嗎?似乎它需要與@XmlDiscriminatorNode等相反。

在此先感謝您的幫助。

回答

0

我遇到了同樣的問題。當傑克遜似乎處理這種情況時,我從Moxy轉到Jackson。

只要改變球衣媒體依賴於您的構建腳本

// 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' 
+0

感謝您的建議。我創建了一個替代解決方案(直接使用JsonObject的),並且拋棄了Moxy編組。下一次,我和傑克遜一起嘗試。 – 2015-01-07 22:18:49

相關問題