2009-05-30 7 views
8

Tôi có một số đối tượng jaxb (được tạo từ mã được tạo từ xsd bởi jaxb) mà tôi cần sao chép. Lớp Jaxb dường như không cung cấp một giao diện để thực hiện điều này một cách dễ dàng. Tôi không thể chỉnh sửa lớp và không thể mở rộng nó - vì vậy tôi cần tạo một phương thức trợ giúp/tiện ích để thực hiện việc này. Đâu là cách tiếp cận lí tưởng nhất?Làm cách nào để sao chép đối tượng JAXB

Trả lời

8

Với mục đích của JAXB, tôi nghĩ cách đơn giản nhất là sắp xếp đối tượng của bạn thành XML và hủy tự động lại đối tượng đó.

Rất nhiều cuộc thảo luận khác trên Google.

Câu hỏi thường gặp về JAXB suggestsbeanlib.

Ngoài ra còn có một số discussion (cũng như liên kết tải xuống) của plugin Cloneable trong jaxb2-commons, mặc dù tôi không thể tìm thấy bất kỳ tham chiếu nào trên trang dự án.

+0

Có - marshall-to-unmarshall hoạt động hoàn hảo. Tôi đang trao cho bạn câu trả lời. Tất nhiên - có một thời gian đánh vào điều này qua serialization - nhưng vì nó không thể được serialized không có nhiều lựa chọn khác ngoài sự phản ánh. –

+0

Xem phần sau để biết ví dụ về mã: http://bdoughan.blogspot.com/2011/03/using-jaxb-to-implement-copy-operation.html –

+0

Thao tác Marshall/unmarshalling khá độc đáo, nhưng đến thời điểm này giải pháp chậm nhất. Bạn có thể nhanh hơn gấp 5 lần bằng cách sử dụng serialization/deserialisation, hoặc khoảng 50x nhanh hơn bằng cách sử dụng nhân bản thực tế. Xem [câu trả lời của tôi ở đây] (http://stackoverflow.com/a/10870833/521799) –

3

Bạn nên thử cc-xjc, có sẵn trên sourceforge. Một trong những tính năng của nó là tạo ra clone() và các bản sao-constructors.

3

Bạn có thể sử dụng Copyable plugin. Nó tạo ra các phương pháp sao chép/sao chép sâu (thậm chí có thể được tùy chỉnh với các chiến lược).

+0

Thật không may, plugin này thêm rất nhiều phụ thuộc vào các tạo phẩm được tạo ra ... –

+0

"Rất nhiều phụ thuộc" là bao nhiêu, chính xác? – lexicore

+0

1, có lẽ ;-) Điều này rất nhiều đối với các POJO đơn giản, có thể chỉ được sao chép bằng cách sử dụng [Object.clone()] (http://docs.oracle.com/javase/7/docs/api/java/ lang/Object.html # clone% 28% 29). Bạn có biết tại sao phụ thuộc được thêm vào không? Ý tôi là, điều gì làm cho các thủ tục nhân bản của jvnet mạnh mẽ hơn? –

2

Tôi đã chạy điểm chuẩn trên các giải pháp khác nhau để sao chép đối tượng JAXB. Dưới đây là một số kết quả:

  1. Sử dụng mofokom's xjc-clone plugin có vẻ là giải pháp nhanh nhất. Nó chỉ cho phép tất cả các đồ tạo tác được tạo của bạn triển khai Cloneable và ghi đè công khai Object.clone(). Thật không may, điều này đã không làm cho nó vào trung tâm Maven (chưa).

  2. Tạo Serializable đồ tạo tác và serialising/deserialising chúng vào một dòng giả là 10x chậm hơn so với sử dụng các cơ chế nhân bản của Java:

    public <T extends Serializable> T clone(T jaxbObject) { 
        ByteArrayOutputStream out = new ByteArrayOutputStream(); 
        ObjectOutputStream o = new ObjectOutputStream(out); 
        o.writeObject(jaxbObject); 
        o.flush(); 
    
        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); 
        ObjectInputStream i = new ObjectInputStream(in); 
        return (T) i.readObject(); 
    } 
    
  3. Marshalling/unmarshalling đối tượng JAXB là một lần nữa 5x chậm hơn so với serialising/deserialising họ. Đây là những gì ykaganovich's giải pháp gợi ý:

    public <T extends Serializable> T clone(T jaxbObject) { 
        StringWriter xml = new StringWriter(); 
        JAXB.marshal(jaxbObject, xml); 
        StringReader reader = new StringReader(xml.toString()); 
        return JAXB.unmarshal(reader, jaxbObject.getClass()); 
    } 
    
+0

Bạn có thể giải thích cách sử dụng plugin xjc-clone không? Tôi không thể tìm thấy bất kỳ tài liệu nào cho plugin này? Bạn có phải sử dụng nó cùng với nhật thực? – CKing

+0

@bot: Thực ra, tôi đã tìm được giải pháp tốt hơn, liên quan đến Maven và plugin chính thức 'jaxb2-basics'. Một giải pháp tương tự với giải pháp mà tôi đã tìm thấy được ghi lại [ở đây] (http://arnekroeger.blogspot.ch/2011/06/java-jaxb-extend-generated-classes.html). Tôi sẽ cập nhật câu trả lời khi có thời gian –

+0

Tôi đã quản lý để tạo các lớp được sinh ra bằng cách sử dụng trình cắm thêm xjc-clone và ant. Có một liên kết mô tả một cách để sử dụng jaxb2-cơ bản plugin với kiến? – CKing

1

Chúng tôi đã sử dụng các plugin jaxb2-cơ bản - nó có sẵn trong Maven repo, cho biết thêm chỉ là một phụ thuộc duy nhất và cũng có thể được sử dụng để tạo công cụ hữu ích khác: bình đẳng , hashCode, toString, giá trị mặc định, vv Xin xem liên kết này để biết chi tiết: http://pragmaticintegrator.wordpress.com/2012/11/20/cloning-a-jaxb-object/

1

Đây là một chủ đề cũ, nhưng tôi đã phải tạo ra các đối tượng cloneable miền JAXB quá và tôi nghĩ rằng marshalling - unmarshalling không phải là giải pháp tốt nhất chắc chắn.

Lý tưởng nhất là bạn nên sao chép các đối tượng trong bộ nhớ bằng cách sử dụng các phương thức sao chép được tạo. Có một plugin Maven (maven-jaxb2-plugin) mà bạn có thể sử dụng cho mục đích này.

Đây là những phần có liên quan trong tập tin pom.xml Maven tôi:

<dependency> 
    <groupId>org.jvnet.jaxb2_commons</groupId> 
    <artifactId>jaxb2-basics</artifactId> 
    <version>0.11.1</version> 
</dependency> 

...

<plugin> 
    <groupId>org.jvnet.jaxb2.maven2</groupId> 
    <artifactId>maven-jaxb2-plugin</artifactId> 
    <executions> 
     <execution> 
      <goals> 
       <goal>generate</goal> 
      </goals> 
     </execution> 
    </executions> 
    <configuration> 
     <extension>true</extension> 
     <schemaDirectory>${basedir}/src/main/xsd</schemaDirectory> 
     <bindingDirectory>${basedir}/src/main/xjb</bindingDirectory> 
     <args> 
      <arg>-Xcopyable</arg> 
     </args> 
     <plugins> 
      <plugin> 
       <groupId>org.jvnet.jaxb2_commons</groupId> 
       <artifactId>jaxb2-basics</artifactId> 
       <version>1.11.1</version> 
      </plugin> 
     </plugins> 
    </configuration> 
</plugin> 

Lưu ý đối số -Xcopyable mà tạo ra các phương pháp nhân bản bên trong của tất cả các đối tượng.

Nếu bạn sử dụng

mvn clean install 

cho việc xây dựng dự án này sẽ tạo ra các lớp miền với thực hiện clone.

Đây là một trích phương pháp nhân bản liên quan trong một trong các lớp miền:

public Object clone() { 
    return copyTo(createNewInstance()); 
} 

public Object copyTo(Object target) { 
    final CopyStrategy2 strategy = JAXBCopyStrategy.INSTANCE; 
    return copyTo(null, target, strategy); 
} 

Bạn có thể tìm các nguồn và các mẫu của dự án cơ bản jaxb2 trên trang này:

https://github.com/highsource/jaxb2-basics/wiki/Sample-Projects

Bản phát hành có các ví dụ hữu ích có thể được tải xuống từ đây:

https://github.com/highsource/jaxb2-basics/releases