2009-07-21 23 views
20

Tôi đang cố gắng để JAXB làm việc với một lớp học groovy của tôi, tuy nhiên, nó xuất hiện nó không hoạt động nhưng phiên bản java nào. Đây là mã ...Làm thế nào để tôi có được Groovy và JAXB để chơi đẹp cùng nhau

Đây là các trường hợp:

Nếu 2 và 3 không được chú ý thì nó hoạt động tốt.

Nếu 1 và 4 được uncomment tôi nhận được:

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 
     2 counts of IllegalAnnotationExceptions 
groovy.lang.MetaClass is an interface, and JAXB can't handle interfaces. 

Nếu 1 và 5 là không chú thích tôi nhận được:

javax.xml.bind.JAXBException: class org.oclc.presentations.simplejaxb.PlayerGroovy 
     nor any of its super class is known to this context. 

Bất kỳ ý tưởng?

Java:

import javax.xml.bind.annotation.XmlRootElement; 

    @XmlRootElement 
    public class Player { 
    } 

Groovy:

import javax.xml.bind.annotation.XmlRootElement 

    @XmlRootElement 
    public class PlayerGroovy { 
    } 

Test:

import org.junit.Test 
    import javax.xml.bind.JAXBContext 
    import javax.xml.bind.Marshaller 
    import org.junit.Assert 

    class PlayerTest { 
     @Test 
     public void testJaXB(){ 
      //1 PlayerGroovy player = new PlayerGroovy() 
      //2 Player player = new Player() 
      StringWriter writer = new StringWriter(); 
      //3 JAXBContext context = JAXBContext.newInstance(Player.class); 
      //4 JAXBContext context = JAXBContext.newInstance(PlayerGroovy.class); 
      //5 JAXBContext context = JAXBContext.newInstance(PlayerGroovy.getClass()); 
      Marshaller m = context.createMarshaller(); 
      m.marshal(player, writer); 
      println(writer) 
      Assert.assertTrue(true) 
     } 
    } 

Trả lời

21

uncommenting 1 và 4 là cách chính xác để thiết JAXB với Groovy. Lý do nó không hoạt động là mỗi Groovy Class có một thuộc tính metaClass trên nó. JAXB đang cố gắng để lộ này như là một tài sản JAXB mà rõ ràng là không thành công. Vì bạn không tự khai báo thuộc tính metaClass, nên không thể chú thích nó để JAXB bỏ qua nó. Thay vào đó bạn đặt XmlAccessType thành NONE. Tính năng tự động phát hiện các thuộc tính tự động của JAXB này để hiển thị dưới dạng các phần tử XML. Sau khi bạn làm điều đó, bạn cần khai báo rõ ràng bất kỳ trường nào bạn muốn hiển thị.

Ví dụ:

@XmlAccessorType(XmlAccessType.NONE) 
@XmlRootElement 
public class PlayerGroovy { 
    @XmlAttribute 
    String value 
} 
+3

+1 câu trả lời tuyệt vời – skaffman

15

Tôi đã có cùng một vấn đề khi để lộ một đối tượng Grails GORM. Sau khi nghiên cứu giải pháp được đăng ở trên, sử dụng @XmlAccessorType(XmlAccessType.NONE), tôi nhanh chóng mệt mỏi vì đánh dấu mọi thứ là @XmlAttribute.

Tôi đang gặp nhiều thành công sử dụng:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlRootElement 
public class PlayerGroovy { 
    String value 
} 

Xem: XmlAccessType

Nhờ câu trả lời ban đầu để có được tôi bắt đầu đi đúng hướng.

+5

Để lưu ý điều này ảnh hưởng đến những gì được trả lại. XmlAccessType.FIELD trả về giá trị của "String value" không phải bất kỳ thao tác nào xảy ra trong getters và setters. Đó là lý do tại sao tôi không thích cách này nhiều. Nhưng có nó làm cho mọi thứ ít tiết. – Jackie

1

Giải pháp dường như không hoạt động trên lớp con trừu tượng. Tôi nghĩ đó là vì trình biên dịch không tạo mã ghi đè getMetaClass. Tôi đã kết thúc bắt chước các bước từ this question như sau:

@XmlAccessorType(XmlAccessType.NONE) 
package groovy.lang; 

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 

Vâng, thật lạ lùng. Trong trường hợp của tôi, tôi có mã như thế này:

package pkg; 
abstract class ScriptMomma extends groovy.lang.Script { 
    // write some nice supporting code here 
} 

Và để thực hiện kịch bản của tôi, tôi có:

def config = new org.codehaus.groovy.control.CompilerConfiguration() 
config.scriptBaseClass = 'pkg.ScriptMomma' 
ScriptMomma mine = new GroovyShell(config).evaluate(scriptFile, 'TheOne') 

Tôi muốn một giải pháp tốt hơn, nhưng ngay bây giờ đây là tất cả tôi có.

+0

Mã này cũng có vẻ hoạt động, mặc dù tôi không chắc đó có thực sự là một ý hay hay không. 'MetaClass metaClass = new DelegatingMetaClass (Cài đặt)' ​​ '@ XmlTransient' ' MetaClass getMetaClass() {' ' metaClass' '}' – ngreen

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