問題描述
我這里有一個情況,試圖充當兩個 API 之間的網關.我需要做的是:
I have a situation here, trying to act as a gateway between two APIs. What I need to do, is:
- 向 APIa 發出請求;
- 將 XML 響應解析(編組)為 java 對象;
- 對其稍作改動;
- 然后以 XML(解組)形式向另一端 (APIb) 提供響應.
問題是我使用同一個對象來解析 API 響應并將響應發送到另一端.
The thing is that I use the same object to parse the API response and to send the response to the other end.
public class ResponseAPI{
@XmlElement(name="ResponseCode") //I receive <ResponseCode> but I need to send <ResultCode>
private String responseCode;
//getter and setter
}
正如評論所說:我收到但我需要發送
as the comment says: I receive but I need to send
有沒有辦法在不創建另一個帶有 ResultCode 的額外類的情況下完成這項工作?
Is there a way to get this done without having to create another extra class which carries ResultCode?
提前致謝!
推薦答案
注意:
Ilya 給出的答案有效,但不保證適用于所有 JAXB 實現,甚至適用于不同版本的 JAXB單個 JAXB 實現.當決定封送哪個元素取決于值的類型時,@XmlElements
注釋很有用(請參閱:http://blog.bdoughan.com/2010/10/jaxb-and-xsd-choice-xmlelements.html).在您的用例中,ResponseCode
和 ResultCode
元素都對應于類型 String
,解組將始終正常工作,但選擇要輸出的元素是任意的.一些 JAXB Impls 可能有最后指定的勝利,但其他人可能很容易獲得第一次勝利.
The answer given by Ilya works but isn't guaranteed to work across all implementations of JAXB or even across versions of a single JAXB implementation. The @XmlElements
annotation is useful when the decision of which element to marshal depends on the type of the value (see: http://blog.bdoughan.com/2010/10/jaxb-and-xsd-choice-xmlelements.html). In your use case both the ResponseCode
and ResultCode
elements correspond to type String
, unmarshalling will always work fine, but the choice of which element to output is arbitrary. Some JAXB Impls may have last specified wins, but others could easily have first wins.
您可以利用 @XmlElementRef
執行以下操作.
You could do the following by leveraging @XmlElementRef
.
響應API
我們將 responseCode
屬性從 String
類型更改為 JAXBElement
.JAXBElement
允許我們存儲元素名稱和值.
We will change the responseCode
property from type String
to JAXBElement<String>
. The JAXBElement
allows us to store the element name as well as the value.
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;
}
}
對象工廠
我們在 ResponseAPI
類上使用的 @XmlElementRef
注釋對應于使用 @XmlRegistry<注釋的類上的
@XmlElementDecl
注釋/代碼>.傳統上,此類稱為 ObjectFactory
,但您可以隨意調用它.
The @XmlElementRef
annotations we used on the ResponseAPI
class correspond to @XmlElementDecl
annotations on a class annotated with @XmlRegistry
. Traditionally this class is called ObjectFactory
but you can call it anything you want.
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);
}
}
演示代碼
input.xml
<responseAPI>
<ResponseCode>ABC</ResponseCode>
</responseAPI>
演示
在創建 JAXBContext
時,我們需要確保包含包含 @XmlElementDecl
注釋的類.
When creating the JAXBContext
we need to ensure that we include the class that contains the @XmlElementDecl
annotations.
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);
}
}
輸出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<responseAPI>
<ResultCode>ABC</ResultCode>
</responseAPI>
這篇關于@XmlElement 具有多個名稱的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!