簡體   English   中英

JAXB使用@XmlJavaTypeAdapter封送Collection的子集

[英]JAXB using @XmlJavaTypeAdapter to marshal a subset of a Collection

我有一個實體,其中包含不同類型的實體的集合。 我想要做的是根據某些條件讓JAXB僅封送集合的一個選定子集。

@XmlRootElement
@Entity
public class A{

    // other fields
    @OneToMany(mappedBy = "x", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Collection<B> bees;

    @XmlJavaTypeAdapter(BFormatter.class)
    public Collection<B> getBees() {
        return bees;
    }

    public void setBees(Collection<B> bees) {
        this.bees= bees;
    }
}


@XmlRootElement
@Entity
public class B{
    // fields
}

public class BFormatter extends XmlAdapter<Collection<B>, Collection<B>>{

    @Override
    public Collection<B> unmarshal(Collection<B> v) throws Exception {
        return v;
    }

    @Override
    public Collection<B> marshal(Collection<B> v) throws Exception {
        Collection<B> subset;
        // making subset
        return subset;
    }

}

這將導致錯誤,指出“ java.util.Collection是一個接口,JAXB無法處理接口”,並且“ java.util.Collection沒有無參數的默認構造函數”。

我在做什么錯,這甚至是正確的解決方法嗎?

重要的是,您不能使Collection(接口)適應JAXB可以處理的內容,因為它不會封送ArrayList或其他Collection類 它旨在封送(豆類) 包含 List或類似字段的類,這意味着“消失”,僅保留其元素的重復 換句話說,沒有XML元素表示ArrayList(或其他任何元素)本身。

因此,適配器必須修改包含元素。 (有關其他選擇,請參見下文。)以下類正在運行; 只需組裝一個Root元素並根據您的設計修改AFormatter。 (注釋參考https://jaxb.java.net/tutorial/section_6_2_9-Type-Adapters-XmlJavaTypeAdapter.html#Type%20Adapters:%20XmlJavaTypeAdapter上的示例。)

(應修改大多數類,以避免將字段公開,但實際上,它是簡短且有效的。)

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root{ // Training
    @XmlElement
    private A a;  // Brochure
    public Root(){}
    public A getA(){ return a; }
    public void setA( A value ){ a = value; }
}

@XmlJavaTypeAdapter(AFormatter.class)
public class A{  // Brochure
    private Collection<B> bees;
    public A(){
        bees = new ArrayList<>();
    }
    public Collection<B> getBees() {
        if( bees == null ) bees = new ArrayList<>();
        return bees;
    }
}

@XmlAccessorType(XmlAccessType.FIELD)
public class B{  // Course
    @XmlElement
    private String id;
    public B(){}
    public String getId(){ return id; }
    public void setId( String value ){ id = value; }
}

public class AFormatter extends XmlAdapter<BeeHive, A>{
    @Override
    public A unmarshal(BeeHive v) throws Exception {
        A a = new A();
        for( B b: v.beeList ){
            a.getBees().add( b );
        }
        return a;
    }
    @Override
    public BeeHive marshal(A v) throws Exception {
    BeeHive beeHive = new BeeHive();
        for( B b: v.getBees() ){
             if( b.getId().startsWith("a") ) beeHive.beeList.add( b ); 
        }                              
        return beeHive;
    }
}

public class BeeHive { // Courses
    @XmlElement(name="b")
    public List<B> beeList = new ArrayList<B>();
}

備選方案:如果B列表的常規獲取者返回應編組的列表,那將非常簡單。 如果應用程序需要全部查看,則可以添加替代的getter。 或者,該類可以具有一個靜態標志,該標志指示getter返回用於編組的List或其他時間的常規列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM