2012-01-31 32 views
14

Một dịch vụ web được trả lại một đối tượng được định nghĩa bởi WSDL là:Làm thế nào để tạo đối tượng java từ 'anyType' được trả về từ dịch vụ bằng JAXB?

<s:complexType mixed="true"><s:sequence><s:any/></s:sequence></s:complexType> 

Khi tôi in ra thông tin lớp của đối tượng này, nó đi kèm như:

class com.sun.org.apache.xerces.internal.dom.ElementNSImpl 

Nhưng tôi cần phải unmarshall này đối tượng như một đối tượng của lớp sau đây:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { 
     "info", 
     "availability", 
     "rateDetails", 
     "reservation", 
     "cancellation", 
     "error" }) 
@XmlRootElement(name = "ArnResponse") 
public class ArnResponse { } 

tôi biết câu trả lời là đúng, vì tôi biết làm thế nào để marshall XML của đối tượng này:

Marshaller m = jc.createMarshaller(); 
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
m.marshal(rootResponse, System.out); 

nào in ra:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ns2:SubmitRequestDocResponse xmlns:ns2="http://tripauthority.com/hotel"> 
    <ns2:SubmitRequestDocResult> 
     <!-- below is the object I'm trying to unmarshall --> 
     <ArnResponse> 
      <Info /> 
      <Availability> 
       <!-- etc--> 
      </Availability> 
     </ArnResponse> 
    </ns2:SubmitRequestDocResult> 
</ns2:SubmitRequestDocResponse> 

Làm thế nào tôi có thể biến các đối tượng ElementNSImpl tôi nhìn thấy vào ArnResponse đối tượng Tôi biết nó đại diện?

Ngoài ra, tôi đang chạy trên AppEngine, nơi quyền truy cập tệp bị hạn chế.

Nhờ sự giúp đỡ

Cập nhật:

Tôi đã thêm @XmlAnyElement(lax=true) chú thích, như vậy:

@XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "", propOrder = { 
     "content" 
    }) 
    @XmlSeeAlso(ArnResponse.class) 
    public static class SubmitRequestDocResult { 

    @XmlMixed 
    @XmlAnyElement(lax = true) 
    protected List<Object> content; 

Nhưng nó không thực hiện bất kỳ sự khác biệt.

Đây có phải là điều cần làm với nội dung là List không?

Dưới đây là đoạn code mà tôi đang cố gắng để truy cập vào các nội dung sau khi nó trở lại từ máy chủ:

List list = rootResponse.getSubmitRequestDocResult().getContent(); 

for (Object o : list) { 
    ArnResponse response = (ArnResponse) o; 
    System.out.println(response); 
} 

Trong đó có các đầu ra:

ngày 31 tháng 1 năm 2012 10:04: 14 AM com.districthp.core.server.ws.alliance.AllianceApi getRates SEVERE: com.sun.org.apache.xerces.internal.dom.ElementNSImpl không thể truyền tới com.districthp.core.server.ws. alliance.response.ArnResponse

trả lời: Câu trả lời

axtavt đã làm các trick. Điều này làm việc:

Object content = ((List)result.getContent()).get(0); 
JAXBContext context = JAXBContext.newInstance(ArnResponse.class); 
Unmarshaller um = context.createUnmarshaller(); 
ArnResponse response = (ArnResponse)um.unmarshal((Node)content); 
System.out.println("response: " + response); 
+0

Tôi có bản sao của tất cả các lược đồ cho các đối tượng phản hồi và WSDL, nếu nó giúp biết điều đó. – Cuga

+4

Lưu ý rằng 'Node' được sử dụng ở đây là' org.w3c.dom.Node'. –

Trả lời

14

Bạn có thể vượt qua đối tượng đó để Unmarshaller.unmarshal(Node), nó sẽ có thể unmarshal nó.

+0

Xin chào, điều đó đã hiệu quả. Cám ơn rất nhiều! – Cuga

1

Từ những gì tôi đã tìm thấy với làm việc với XML, anyType có thể đại diện cho bất kỳ đối tượng, do đó, điều gần gũi nhất bạn có thể ánh xạ nó trở lại là java.lang.Object. (Bên cạnh thực tế rằng anyType về mặt kỹ thuật có thể là lỗ hổng bảo mật, cho phép ai đó tiêm bất cứ thứ gì, bao gồm cả nhị phân độc hại vào vị trí đó, và không có gì ngăn chặn nó vì lược đồ của bạn cho phép nó.)

Bạn nên thay đổi lược đồ để cho phép ánh xạ tới đối tượng tùy chỉnh của mình. Điều này rõ ràng hơn cả từ quan điểm lập trình, quan điểm tiêu thụ và quan điểm bảo mật.

Trong khi chờ bạn không thể làm điều đó, tôi khuyên bạn nên lưu trữ loại dưới dạng thuộc tính của phần tử. Bạn có thể cần phải viết mã tùy chỉnh sau đó để giúp bạn chuyển đổi các anyType trở lại đối tượng đó, nhưng ít nhất bạn biết loại của nó sau đó.

Hai xu của tôi dựa trên kinh nghiệm của tôi (chủ yếu là trong lĩnh vực tích hợp).

+1

Vâng, nếu tôi có thể, tôi sẽ không sử dụng 'anyType', nhưng chúng tôi đang tích hợp với lược đồ của người khác, vì vậy chúng tôi đang mắc kẹt với nó. – Cuga

4

Bạn có thể sử dụng @XmlAnyElement(lax=true). Điều này sẽ chuyển đổi XML với các phần tử gốc đã biết (@XmlRootElement hoặc @XmlElementDecl) cho các đối tượng miền. Đối với một ví dụ xem:

+1

Tôi đã kiểm tra nhưng chú thích đã có ở đó. Vui lòng xem câu hỏi được cập nhật của tôi. Một lần nữa xin cảm ơn sự giúp đỡ của bạn và tôi đã xem qua blog của bạn trước đây và các câu trả lời khác của bạn ở đây trên SO. Công việc của bạn đã giúp tôi rất nhiều. – Cuga

+0

Cảm ơn, nó đã giải quyết được vấn đề của tôi! –

Các vấn đề liên quan