McC*_*Coy 1 java xml jaxb xml-parsing
我这里有一个情况,试图充当两个 API 之间的网关。我需要做的是:
问题是我使用相同的对象来解析 API 响应并将响应发送到另一端。
public class ResponseAPI{
@XmlElement(name="ResponseCode") //I receive <ResponseCode> but I need to send <ResultCode>
private String responseCode;
//getter and setter
}
Run Code Online (Sandbox Code Playgroud)
正如评论所说:我收到但我需要发送
有没有办法在不必创建另一个带有 ResultCode 的额外类的情况下完成这项工作?
提前致谢!
您可以使用@XmlElements annotaion尝试下一个解决方案
@XmlAccessorType(XmlAccessType.FIELD)
public class ResponseAPI
{
@XmlElements(
{
@XmlElement(name = "ResponseCode"),
@XmlElement(name = "ResultCode")
})
private String responseCode;
// ...
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,ResponseCode和ResultCode将在解组(xml -> 对象)ResultCode期间和仅在编组(对象 - > xml)期间使用。
所以你可以像解组 XML
<responseAPI>
<ResponseCode>404</ResponseCode>
</responseAPI>
Run Code Online (Sandbox Code Playgroud)
编组对象后看起来像
<responseAPI>
<ResultCode>404</ResultCode>
</responseAPI>
Run Code Online (Sandbox Code Playgroud)
笔记:
Ilya 给出的答案有效,但不能保证适用于 JAXB 的所有实现,甚至跨单个 JAXB 实现的版本。@XmlElements当决定封送哪个元素取决于值的类型时, 该注释很有用(请参阅:http: //blog.bdoughan.com/2010/10/jaxb-and-xsd-choice-xmlelements.html)。在您的用例中,ResponseCode和ResultCode元素都对应于 type String,解组始终可以正常工作,但选择输出哪个元素是任意的。一些 JAXB Impl 可能具有最后指定的胜利,但其他 JAXB Impl 可能很容易获得首次胜利。
您可以利用@XmlElementRef.
响应API
我们将responseCode属性从 type更改String为JAXBElement<String>. 允许JAXBElement我们存储元素名称和值。
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class ResponseAPI{
@XmlElementRefs({
@XmlElementRef(name = "ResponseCode"),
@XmlElementRef(name = "ResultCode")
})
private JAXBElement<String> responseCode;
public JAXBElement<String> getResponseCode() {
return responseCode;
}
public void setResponseCode(JAXBElement<String> responseCode) {
this.responseCode = responseCode;
}
}
Run Code Online (Sandbox Code Playgroud)
对象工厂
@XmlElementRef我们在类上使用的注释对应ResponseAPI于@XmlElementDecl用 注释的类上的注释@XmlRegistry。传统上该类的名称是这样的ObjectFactory,但您可以将其命名为任何您想要的名称。
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;
@XmlRegistry
public class ObjectFactory {
@XmlElementDecl(name="ResponseCode")
public JAXBElement<String> createResponseCode(String string) {
return new JAXBElement<String>(new QName("ResponseCode"), String.class, string);
}
@XmlElementDecl(name="ResultCode")
public JAXBElement<String> createResultCode(String string) {
return new JAXBElement<String>(new QName("ResultCode"), String.class, string);
}
}
Run Code Online (Sandbox Code Playgroud)
输入.xml
<responseAPI>
<ResponseCode>ABC</ResponseCode>
</responseAPI>
Run Code Online (Sandbox Code Playgroud)
演示
创建时,JAXBContext我们需要确保包含包含注释的类@XmlElementDecl。
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(ResponseAPI.class, ObjectFactory.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("Scratch/src2/forum24554789/input.xml");
ResponseAPI responseAPI = (ResponseAPI) unmarshaller.unmarshal(xml);
ObjectFactory objectFactory = new ObjectFactory();
String responseCode = responseAPI.getResponseCode().getValue();
JAXBElement<String> resultCodeJAXBElement = objectFactory.createResultCode(responseCode);
responseAPI.setResponseCode(resultCodeJAXBElement);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(responseAPI, System.out);
}
}
Run Code Online (Sandbox Code Playgroud)
输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<responseAPI>
<ResultCode>ABC</ResultCode>
</responseAPI>
Run Code Online (Sandbox Code Playgroud)