2013-03-06 18 views
7

Có ai biết cách đính kèm tùy chỉnh XmlAdapter vào các đối tượng có trong danh sách không đồng nhất (như Danh sách) không? Ví dụ - giả sử chúng ta có một lớp chứa một danh sách các đối tượng linh tinh:JAXB: XmlAdapter cho Danh sách <Object> mục

@XmlRootElement(name = "container") 
public class Container { 
    private List<Object> values = new ArrayList<Object>(); 

    @XmlElement(name = "value") 
    public List<Object> getValues() { 
     return values; 
    } 

    public void setValues(List<Object> values) { 
     this.values = values; 
    } 
} 

Nếu chúng ta đặt String -s, Integer -s và vân vân họ sẽ được ánh xạ theo mặc định. Bây giờ giả sử chúng ta muốn đặt một đối tượng tùy chỉnh:

public class MyObject { 
    //some properties go here 
} 

Các giải pháp rõ ràng là để viết một bộ chuyển đổi tùy chỉnh:

public class MyObjectAdapter extends XmlAdapter<String, MyObject> { 
    //marshalling/unmarshalling 
} 

Nhưng tiếc là nó không làm việc với gói cấp @XmlJavaTypeAdapter - bộ chuyển đổi chỉ không bao giờ gọi là marhalling thất bại. Và tôi không thể áp dụng trực tiếp cho getValues() vì có thể có các loại đối tượng khác. @XmlJavaTypeAdapter chỉ hoạt động nếu tôi có một lĩnh vực loại MyObject trong container (cũng với gói cấp annotaton):

public class Container { 
    private MyObject myObject; 
} 

Nhưng đây không phải là những gì tôi muốn - Tôi muốn có một danh sách các đối tượng tùy ý. Tôi đang sử dụng triển khai JAXB chuẩn của Sun:

<dependency> 
    <groupId>com.sun.xml.bind</groupId> 
    <artifactId>jaxb-impl</artifactId> 
    <version>2.2.3-1</version> 
</dependency> 

Bất kỳ ý tưởng nào về cách lập bản đồ?

P.S .: Một chút làm rõ - Tôi muốn tránh chú thích MyObject với chú thích JAXB. Nó có thể là một lớp học từ thư viện của bên thứ ba mà không thuộc quyền kiểm soát của tôi. Vì vậy, mọi thay đổi phải nằm ngoài số MyObject.

+0

'ContextResolver' có thể là giải pháp tốt ở đây ... – Mark

Trả lời

0

Bạn có thể thử thay đổi MyObjectAdapter để mở rộng XmlAdapter<String, List<Object>>. Vì vậy, nó sẽ giống như thế này:

public class MyObjectAdapter extends XmlAdapter<String, List<Object>> { 
    //marshalling/unmarshalling 
} 

Khi bạn cũng có thêm một chú thích XmlJavaTypeAdapter đến getter trong lớp Container của bạn, nó sẽ làm việc.

@XmlRootElement(name = "container") 
public class Container { 
    private ArrayList<Object> values = new ArrayList<Object>(); 

    @XmlElement(name = "value") 
    @XmlJavaTypeAdapter(MyObjectAdapter.class) 
    public ArrayList<Object> getValues() { 
     return values; 
    } 

    public void setValues(ArrayList<Object> values) { 
     this.values = values; 
    } 
}