2012-01-30 11 views
8

Mã tôi đang làm việc đang sử dụng jaxb2-maven-plugin từ org.codehaus.mojo để tạo các lớp Java từ lược đồ XSD. Tôi đang tìm một cách để tự động thực hiện các phương thức equals()hashCode() cho các lớp đó, nhưng có vẻ như không có cách nào. Tôi biết rằng có các plugin JAXB2 Maven khác làm điều đó (http://confluence.highsource.org/display/J2B/Home chẳng hạn), nhưng tôi đã tự hỏi liệu có ai trong số các bạn gặp sự cố này trước đây hay không và liệu có cách nào để sửa chữa nó. Tôi đang tạo ra các lớp học bằng cách sử dụng mục tiêu xjc.Tạo hashCode() và bằng() khi tạo các lớp Java bằng cách sử dụng Mojo Jaxb2 maven plugin

Trả lời

12

JAXB2 Khái niệm cơ bản bạn đang đề cập không phải là tài sản của maven-jaxb2-plugin, nó là một bộ độc lập các plugin JAXB 2.x mà bạn có thể sử dụng với XJC - hoặc jaxb2-maven-plugin hoặc bất kỳ thứ gì.

 <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>jaxb2-maven-plugin</artifactId> 
      <version>1.3.1</version> 
      <executions> 
       <execution> 
        <id>xjc</id> 
        <goals> 
         <goal>xjc</goal> 
        </goals> 
       </execution> 
      </executions> 
      <configuration> 
       <arguments> 
        <argument>-Xequals</argument> 
        <argument>-XhashCode</argument> 
       </arguments> 
      </configuration> 
      <dependencies> 
       <dependency> 
        <groupId>org.jvnet.jaxb2_commons</groupId> 
        <artifactId>jaxb2-basics</artifactId> 
        <version>0.11.1</version> 
       </dependency> 
      </dependencies> 
     </plugin> 

Điều tôi muốn hỏi - tại sao không chỉ sử dụng maven-jaxb2-plugin? Nó có nhiều chức năng hơn so với plugin Codehaus - bao gồm hỗ trợ cấu hình cho các plugin JAXB2.

+0

Tôi đã đi cho nó thực sự! Cảm ơn :) – manub

+1

Bạn có chắc chắn điều này đang hoạt động không? Tôi nhận được "Không thể thực thi mục tiêu org.codehaus.mojo: jaxb2-maven-plugin: 1.5: xjc (xjc) trên dự án XXX: thông số không được công nhận -Xequals" HOẶC "Không thể tìm thấy tạo phẩm" tùy thuộc vào phiên bản tôi sử dụng. Đối với các plugin khác, tất cả các liên kết hướng tới nó đều bị hỏng. – ampofila

+0

@ampofila Không, tôi không chắc chắn về XML cụ thể này, chỉ có những điều cơ bản về jaxb2 không phụ thuộc vào bất kỳ plugin Maven cụ thể nào. Tôi chỉ sử dụng plugin maven-jaxb2. Plugin được lưu trữ trong repo trung tâm của Maven, do đó chắc chắn có sẵn: http://mvnrepository.com/artifact/org.jvnet.jaxb2.maven2/maven-jaxb2-plugin Tôi đang khởi động lại máy chủ tài liệu. – lexicore

4

Tôi thật sự không đồng ý với việc sử dụng các lớp được tạo bởi JAXB làm đối tượng kinh doanh trong mã của bạn. Các lớp được tạo bởi JAXB là các bean chỉ có nghĩa là về cơ bản di chuyển thông tin phần tử từ tệp xml, tới các trường của bean. Cá nhân tôi luôn có dịch vụ SOAP của tôi chuyển đổi các lớp bean được tạo ra này thành các đối tượng nghiệp vụ thực tế của tôi, như XML-> Java và ngược lại không phải lúc nào cũng đen trắng. Lưu ý rằng đây là ý kiến ​​cá nhân của tôi, và sẽ yêu một số người khác cân nhắc những gì họ làm trong tình huống này.

Để trả lời câu hỏi của bạn, hãy sử dụng một trình cắm khác hoặc chỉ sử dụng IDE của bạn để thực hiện một số phương thức equals và hashCode.

Hy vọng điều đó sẽ hữu ích.

CHỈNH SỬA:

Tôi quên đặt lý do cho điều này, xin lỗi. Chúng ta hãy nói trong phiên bản tiếp theo của dự án của bạn, bạn muốn thêm một số hành vi khác vào các lớp được tạo JAXB của bạn, nhưng cũng muốn thực hiện một số thay đổi đối với lược đồ của bạn. Bây giờ bạn đang tạo lại các lớp đã tạo JAXB, đưa các hành vi cũ trở lại và làm cho ứng dụng của bạn dễ bị lỗi hơn theo ý kiến ​​của tôi. Các lớp được tạo ra JAXB được cho là phản ánh các loại lược đồ XML của bạn (và do đó các thông điệp SOAP của bạn) không phải là logic nghiệp vụ của bạn. Hy vọng rằng có ý nghĩa.

+0

Tôi đồng ý với điều đó và chúng tôi có các Đối tượng kinh doanh riêng biệt. Lý do chính tôi sẽ cần đó là để viết bài kiểm tra đơn vị, nhưng cảm ơn cho tip tuy nhiên! – manub

+1

manub: Bạn có thể sử dụng EqualsBuilder.reflectionEquals của Apache Commons Lang để so sánh các lớp được tạo JAXB của bạn mà không thêm hashCode và bằng thông qua một plugin Maven. –

+0

@ChrisEineke Với tất cả các hình phạt hiệu suất của sự phản ánh. – lexicore

2

Bạn cũng có thể muốn xem xét sử dụng fluent builder interface (tạo điều kiện cho việc xử lý các lớp JAXB được tạo) và tham chiếu đến tệp danh mục trong trường hợp bạn tham chiếu lược đồ lõi xmldsig (tăng tốc quá trình tạo) Các lược đồ từ xa từ W3C được truy vấn - máy chủ của chúng thường trì hoãn phản hồi).

 <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>jaxb2-maven-plugin</artifactId> 
      <version>1.5</version> 
      <dependencies> 
       <dependency> 
        <groupId>net.java.dev.jaxb2-commons</groupId> 
        <artifactId>jaxb-fluent-api</artifactId> 
        <version>2.0.1</version> 
        <exclusions> 
         <exclusion> 
          <groupId>com.sun.xml</groupId> 
          <artifactId>jaxb-xjc</artifactId> 
         </exclusion> 
        </exclusions> 
       </dependency> 
       <dependency> 
        <groupId>org.jvnet.jaxb2_commons</groupId> 
        <artifactId>jaxb2-basics</artifactId> 
        <version>0.6.4</version> 
        <exclusions> 
         <exclusion> 
          <groupId>com.sun.xml</groupId> 
          <artifactId>jaxb-xjc</artifactId> 
         </exclusion> 
        </exclusions> 
       </dependency> 
      </dependencies> 
      <executions> 
       <execution> 
        <goals> 
         <goal>xjc</goal> 
        </goals> 
       </execution> 
      </executions> 
      <configuration> 
       <schemaDirectory>${basedir}/src/main/resources/xsd</schemaDirectory> 
       <packageName>[your package name goes here]</packageName> 
       <outputDirectory>${build.directory}/generated/src/main/java</outputDirectory> 
       <bindingDirectory>${basedir}/src/main/resources/xsd</bindingDirectory> 
       <extension>true</extension> 
       <catalog>${basedir}/src/main/resources/xsd-catalog/catalog.cat</catalog> 
       <extension>true</extension> 
       <arguments>-Xfluent-api -Xequals -XhashCode -XtoString</arguments> 
      </configuration> 
     </plugin> 

Sau đây là cách các tập tin Danh mục trông giống như:

-- 
    sample catalog file. 

    double hyphens are used to begin and end a comment section. 
-- 

SYSTEM "http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd" "xmldsig-core-schema.xsd" 

Và đây là các liên kết đến các xmldisg-core-schema.xsd: http://www.w3.org/TR/xmldsig-core/xmldsig-core-schema.xsd

Xin lưu ý rằng liên kết không phải là bị hỏng - máy chủ W3C chỉ trì hoãn phản hồi vài giây. Tôi có thể rất cồng kềnh nếu điều đó xảy ra trong quá trình xây dựng tự động của bạn, bao gồm việc tạo JAXB.

1

Câu trả lời của tôi dành cho những người không đủ khả năng phụ thuộc phần ba vào mã được tạo của họ.

Plugin org.jvnet.jaxb2_commons:jaxb2-basics thêm rất nhiều org.jvnet bao gồm trong mã được tạo và dự án của bạn sẽ tùy thuộc vào org.jvnet.jaxb2_commons:jaxb2-basics-runtime.

Plugin org.andromda.thirdparty.jaxb2_commons:commons-lang-plugin tạo mã phụ thuộc vào commons-lang:commons-lang. Sự phụ thuộc này có thể dễ chịu hơn tùy theo tình huống.

Cuối cùng tôi tìm thấy this source code, nó có thể được bao gồm trong com.sun.xml.bind:jaxb-xjc tại một số điểm (phiên bản 2.2.4?), Nhưng cho đến lúc đó tôi không thể thấy bất kỳ giải pháp nào khác ngoài viết plugin của riêng bạn.

PS: Tôi không thể truy cập confluence.highsource.org, tôi nhận được 404. Tôi đoán nó có thể hữu ích.

PPS: Trong trường hợp của tôi, ứng dụng tôi đang xây dựng được nhắm mục tiêu đến môi trường có bộ thư viện Java cho phép rất hạn chế (các hạn chế bảo mật vô hạn). Tôi hơi thất vọng bởi thực tế rằng jaxb2_commons bao gồm một bó phụ thuộc org.jvnet trong nguồn được tạo ra, chỉ để thêm phương thức nhàm chán equals. Tôi có thể hiểu được chiến lược của jvnet, công cụ của họ rất mạnh mẽ, tôi chỉ có thể đang cố gắng và sử dụng một cái búa tạ để crack một hạt. Tuy nhiên, tôi xin lỗi để lưu ý rằng thật khó để tìm ra một công cụ phù hợp cho hoàn cảnh của tôi.

+0

điều quan trọng là phải nói rằng tùy chọn sử dụng với plugin andromda là '-Xcommons-lang'. – logoff

2

Đây là cách dễ nhất để thực hiện. Vui lòng cập nhật phiên bản theo yêu cầu của bạn.

<plugin> 
        <groupId>org.codehaus.mojo</groupId> 
        <artifactId>jaxb2-maven-plugin</artifactId> 
        <version>1.5</version> 
        <dependencies> 
         <dependency> 
          <groupId>org.jvnet.jaxb2_commons</groupId> 
          <artifactId>jaxb2-commons-lang</artifactId> 
          <version>2.3</version> 
         </dependency> 
        </dependencies> 
        <executions> 
         <execution> 
          <id>JAXB generate content classes</id> 
          <phase>generate-sources</phase> 
          <goals> 
           <goal>xjc</goal> 
          </goals> 
          <configuration> 
           <schemaDirectory>${project.basedir}/src/main/resources/schema</schemaDirectory> 
           <outputDirectory>${project.build.directory}/generated-sources/jaxb</outputDirectory> 
           <schemaFiles>**/*.xsd</schemaFiles> 
           <packageName>com.lexus.web.content.model</packageName> 
           <arguments>-Xcommons-lang</arguments> 
          </configuration> 
         </execution> 
        </executions> 
       </plugin> 
1

Ngoài ra còn có plugin plugin dành cho JAXB không nhất thiết tạo phụ thuộc cho mã của bên thứ ba. Thêm vào đó, nó là một mẫu thiết kế "Builder" thực sự, trong khi plugin "fluent-api" chỉ thêm các phương thức giống như builder cho các lớp được tạo ra. Nó là: https://github.com/mklemm/jaxb2-rich-contract-plugin Nó cũng có các tùy chọn để làm cho các lớp được tạo ra không thay đổi được và nó có thể tạo ra các phương thức sao chép trạng thái của các đối tượng hiện có thành một thể hiện mới, cũng hỗ trợ bản sao đối tượng "một phần".