我尝试使用Spring的RestTemplate和JAXB解组从外部Web服务收到的以下非常简单的XML:
<?xml version="1.0" encoding="utf-8"?>
<double xmlns="http://www.example.com/">0.061</double>
这是我用来解组XML的类。我已经尝试了@XmlRootElement,@ XMLElement和@XmlValue的各种组合,但无法让它工作。
@XmlRootElement
public class ExchangeRateWebServiceResponse {
private double rate;
@XmlElement(name = "double")
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
}
使用RestTemplate执行Web服务调用的方法:
public double getExchangeRate(String fromCurrency, String toCurrency,
String exchangeRateURL) {
RestTemplate restTemplate = new RestTemplate();
ExchangeRateWebServiceResponse result =
restTemplate.getForObject(exchangeRateURL,
ExchangeRateWebServiceResponse.class,
fromCurrency, toCurrency);
return result.getRate();
}
这是我得到的例外:
org.springframework.http.converter.HttpMessageNotReadableException: Could not unmarshal to [class za.co.example.server.finance.ExchangeRateWebServiceResponse]: unexpected element (uri:"http://www.example.com/", local:"double"). Expected elements are <{}exchangeRateWebServiceResponse>; nested exception is javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.example.com/", local:"double"). Expected elements are <{}exchangeRateWebServiceResponse>
at org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter.readFromSource(Jaxb2RootElementHttpMessageConverter.java:82)
at org.springframework.http.converter.xml.AbstractXmlHttpMessageConverter.readInternal(AbstractXmlHttpMessageConverter.java:61)
at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:153)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:103)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:496)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:452)
at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:222)
at za.co.example.server.finance.ExchangeRateWebService.getExchangeRate(ExchangeRateWebService.java:21)
at za.co.example.test.suites.integration.component.external.ExchangeRateWebserviceTests.testGetZARToGBPRate_shouldReturnAnExchangeRate(ExchangeRateWebserviceTests.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.example.com/", local:"double"). Expected elements are <{}exchangeRateWebServiceResponse>
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:647)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:243)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:238)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:105)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1048)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:483)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:465)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:135)
at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:203)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:175)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:125)
at org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter.readFromSource(Jaxb2RootElementHttpMessageConverter.java:74)
... 34 more
答案 0 :(得分:3)
你需要在你的java对象上有命名空间。
@XmlElement(name = "double", namespace = "http://www.example.com/" )
修改
您可以在单独的package-info类中配置命名空间,并将其放在java类包
中@XmlSchema(
xmlns = { namespace = "http://www.example.com/",
elementFormDefault = XmlNsForm.QUALIFIED)
这样您就可以只在根级别定义名称空间,不需要在每个xml元素上定义,也可以配置多个名称空间。
此链接将提供有关package-info.java
的更多详细信息答案 1 :(得分:0)
在@pappu_kutty的帮助下,我得出结论我需要在@XmlRootElement中指定命名空间和元素名称,然后将@XmlValue添加到getRate()或setRate()以获取根元素的值。
@XmlRootElement(name = "double", namespace = "http://www.example.com/")
public class ExchangeRateWebServiceResponse {
private double rate;
@XmlValue
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
}