gpt4 book ai didi

java - JAXB 使用 @XmlJavaTypeAdapter 编码(marshal) Collection 的子集

转载 作者:行者123 更新时间:2023-12-02 05:36:13 35 4
gpt4 key购买 nike

我有一个实体,其中包含不同类型实体的集合。我想要做的是让 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 是一个接口(interface),JAXB 无法处理接口(interface)”以及“java.util.Collection 没有无参数默认构造函数。”

我做错了什么,这是正确的方法吗?

最佳答案

重要的是,您无法将 Collection(接口(interface))调整为 JAXB 可以处理的内容,因为它不会编码(marshal) ArrayList 或其他一些集合类。它旨在编码包含列表或类似字段的(bean)类,这意味着“消失”,仅保留为其元素的重复。换句话说,不存在代表 ArrayList(或其他内容)本身的 XML 元素。

因此,适配器必须修改包含元素。 (请参阅下面的替代方案。)以下类正在工作;只需组装一个 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。或者,该类可以有一个静态标志,指示 getter 返回一个用于编码的列表,或者在其他时候返回常规列表。

关于java - JAXB 使用 @XmlJavaTypeAdapter 编码(marshal) Collection 的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24936430/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com