![](/img/trans.png)
[英]JAXB @XmlAnyElement with XmlAdapter does not make a call to the unmarshal method
[英]@XmlAnyElement does not unmarshal into specific Java type, but stop at JAXBElement
為了學習如何使用@XmlAnyElement
,我創建了以下測試服務:
@WebService(serviceName = "TestServices")
@Stateless()
public class TestServices {
@WebMethod(operationName = "testMethod")
public ServiceResult testMethod() {
ServiceResult result = new ServiceResult();
result.addObject(new SimpleObj(1, 2));
result.addObject(new SimpleObj(3, 4));
return result;
}
}
SimpleObj
是具有2個int
字段的簡單類。 下面是ServiceResult
類的代碼:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({SimpleObj.class})
public class ServiceResult {
@XmlAnyElement(lax = true)
private List<Object> body;
public void addObject(Object objToAdd) {
if (this.body == null)
this.body = new ArrayList();
this.body.add(objToAdd);
}
// Getters and Setters
}
為了使用上述服務,我使用以下Main
類創建了一個appclient:
public class Main {
@WebServiceRef(wsdlLocation = "META-INF/wsdl/localhost_8080/TestServices/TestServices.wsdl")
private static TestServices_Service service;
private static TestServices port;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
port = service.getAdminServicesPort();
ServiceResult result = port.testMethod();
for (Object o : result.getAny()) {
System.out.println("TEST: " + o);
}
}
}
根據文檔,使用@XmlAnyElement
,解組器會急切將此元素解組到JAXB對象。 但是,我觀察到的是JAXB僅將我的對象解析為JAXBElement
而不是完全解析為SimpleObj
。
如果您能向我展示如何從ServiceResult
獲取SimpleObj
,我將不勝感激。
更新 :
下面是SimpleObj
類:
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class SimpleObj {
private int a;
private int b;
public SimpleObj() {}
public SimpleObj(int a, int b) {
this.a = a;
this.b = b;
}
// Getters and Setters
}
我無法重現您看到的問題。 下面是一些直接與JAXB交互的演示代碼。
import java.io.*;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(ServiceResult.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StringReader xml = new StringReader("<serviceResult><simpleObj/><simpleObj/></serviceResult>");
ServiceResult result = (ServiceResult) unmarshaller.unmarshal(xml);
for(Object item : result.getBody()) {
System.out.println(item.getClass());
}
}
}
運行演示代碼的輸出顯示,它是在@XmlAnyElement(lax=true)
注釋的字段中的SimpleObj
實例。
class forum27871349.SimpleObj
class forum27871349.SimpleObj
在旁注中,我閱讀了您在@XmlAnyElement上的博客文章,而且從未見過您必須在任何示例中都包含@XmlSeeAlso({SimpleObj.class})。
我不確定為什么我在示例中從未使用@XmlSeeAlso
。
但是,在我的情況下,如果我沒有這個,我會得到這樣的錯誤:***類或其任何超類都不為該上下文所知。 如果您還可以告訴我是否有一種方法可以讓消費者在不使用@XmlSeeAlso的情況下了解所有這些類,那就太好了
當您自己創建JAXBContext
,只需要包含您在@XmlSeeAlso
批注中引用的所有內容, @XmlSeeAlso
作為用來引導JAXBContext
的類的一部分。
JAXBContext jc = JAXBContext.newInstance(ServiceResult.class, SimpleObj.class);
在您沒有直接訪問JAXBContext
的JAX-WS(或JAX-RS)設置中,我建議像您一樣使用@XmlSeeAlso
批注。
關於@XmlAnyElement,我從文檔中認為,如果解組器無法將元素解組到JAXB對象或JAXBElement對象中,則至少會得到一個DOM節點。
當您使用@XmlAnyElement(lax=true)
映射屬性時,將發生以下情況:
@XmlRootElement
,則您將獲得該類的實例。 ObjectFactory
上一個類的@XmlElementDecl
或另一個帶有@XmlRegistry
注釋的類,那么您將獲得該類的實例,該實例包裝在JAXBElement
的實例中。 Element
。 我將在下面舉例說明。
的ObjectFactory
import javax.xml.namespace.QName;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
@XmlRegistry
public class ObjectFactory {
@XmlElementDecl(name="simpleObjJAXBElement")
public JAXBElement<SimpleObj> createSimpleObj(SimpleObj simpleObj) {
return new JAXBElement<SimpleObj>(new QName("simpleObjJAXBElement"), SimpleObj.class, simpleObj);
}
}
演示
import java.io.*;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(ServiceResult.class, ObjectFactory.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StringReader xml = new StringReader("<serviceResult><simpleObj/><unmapped/><simpleObjJAXBElement/></serviceResult>");
ServiceResult result = (ServiceResult) unmarshaller.unmarshal(xml);
for(Object item : result.getBody()) {
System.out.println(item.getClass());
}
}
}
產量
class forum27871349.SimpleObj
class com.sun.org.apache.xerces.internal.dom.ElementNSImpl
class javax.xml.bind.JAXBElement
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.