2010-02-15 25 views
8

Tôi đang cố sắp xếp một đối tượng có một đối tượng là một trong các trường của nó.JAXB Marshalling Objects với trường java.lang.Object

@XmlRootElement 
public class TaskInstance implements Serializable { 
    ... 
    private Object dataObject; 
    ... 
} 

Các DataObject thể là một trong nhiều khác nhau loại không rõ, nên quy định cụ thể từng nơi không chỉ là không thực tế nhưng không thể. Khi tôi cố gắng sắp xếp đối tượng, nó nói rằng lớp học không được biết đến trong ngữ cảnh.

MockProcessData mpd = new MockProcessData(); 
TaskInstance ti = new TaskInstance(); 
ti.setDataObject(mpd); 

String ti_m = JAXBMarshall.marshall(ti); 

"MockProcessData cũng như bất kỳ siêu lớp nào được biết đến trong ngữ cảnh này". là những gì tôi nhận được.

Có cách nào xung quanh lỗi này không?

+0

bạn đang cố gắng gì để serialize MockProcessData tới? tức là đại diện mong muốn là gì? – mtpettyp

+0

Là người dùng JAXB lần đầu tiên, tôi có cùng một vấn đề cố gắng sắp xếp một cây đối tượng được tạo từ đầu, tức là không được tạo từ một XSD đã biên dịch. Trong thực tế, tôi muốn làm điều đó theo cách khác, và tạo lược đồ từ các lớp khi tôi có mã hoạt động. Tôi đã cố gắng gói đối tượng của tôi trong một JAXBElement như mô tả, và tôi đã chính xác giống như "Foobar không được biết đến bối cảnh này" tin nhắn như trước, vì vậy tôi không xa hơn về phía trước. –

+0

Hey Dasmotiu - Tôi đã kết thúc bao gồm chú thích @XMLSeeAlso và cung cấp tất cả các lớp mà nó có thể cố gắng điều chỉnh đối tượng. Ví dụ: @XmlSeeAlso ({ StringType.class, DecimalType.class, NumericType.class, BooleanType.class, StructType.class, ListType.class, DateType.class, SpatialType.class }) lớp trừu tượng công khai FieldType { – jcovert

Trả lời

6

JAXB không thể đối chiếu bất kỳ đối tượng cũ nào vì nó không biết cách thực hiện. Ví dụ, nó sẽ không biết những gì tên phần tử để sử dụng.

Nếu bạn cần xử lý loại ký tự đại diện này, giải pháp duy nhất là bọc các đối tượng trong đối tượng JAXBElement, chứa đủ thông tin cho JAXB đối chiếu với XML.

Hãy thử một cái gì đó như:

QName elementName = new QName(...); // supply element name here 
JAXBElement jaxbElement = new JAXBElement(elementName, mpd.getClass(), mpd); 
ti.setDataObject(jaxbElement); 
+0

Có vẻ tốt, nhưng tôi có hai câu hỏi về điều này. Thứ nhất, tên phần tử - nó không chính xác rõ ràng với cái mà nó được sử dụng, nhưng tôi cho rằng "dataObject" sẽ là đủ? Và thứ hai, JAXBElement là một kiểu thô, và trình biên dịch cảnh báo tôi rằng nó nên được parametrized. Tôi biết cảnh báo là một cảnh báo và không phải là lỗi, nhưng vì tôi ở trong lãnh thổ xa lạ, có vẻ như một ý tưởng hay để tìm hiểu thêm. Tôi không chắc mình sẽ làm gì với nó, vì tôi đang đối phó với 'Object'. Cảm ơn! – jcovert

+0

@jcovert: Tên phần tử và không gian tên có thể là bất kỳ thứ gì bạn thích, vì vậy có, 'dataObject' sẽ ổn. Đối với các generics, chỉ cần sử dụng 'JaxbElement ', nó chỉ là một thứ biên dịch, JAXB không quan tâm đến thời gian chạy. – skaffman

+1

Tôi mất một vài phút để làm cho nó hoạt động, nhưng thực sự đây là một giải pháp tuyệt vời. Một thay đổi nhỏ (đối với bất kỳ ai khác có thể gặp phải vấn đề tương tự): 'ti.setDataObject (jaxbElement)' nên là 'ti.setDataObject (jaxbElement.getValue())' Cảm ơn bạn đã giúp đỡ! – jcovert

0

Phương pháp:

public String marshallXML(Object object) { 
     JAXBContext context; 
     try { 
      context = JAXBContext.newInstance(object.getClass()); 
      StringWriter writer = new StringWriter(); 
      Marshaller marshaller = context.createMarshaller(); 
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
      marshaller.marshal(object, writer); 
      String stringXML = writer.toString(); 
      return stringXML; 
     } catch (JAXBException e) { 

     } 
} 

mẫu:

import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
@XmlRootElement 
public class Customer { 
    String name; 
    int id; 
    public String getName() { 
     return name; 
    } 
    @XmlElement 
    public void setName(String name) { 
     this.name = name; 
    } 
    public int getId() { 
     return id; 
    } 
    @XmlAttribute 
    public void setId(int id) { 
     this.id = id; 
    } 
} 
Các vấn đề liên quan