gpt4 book ai didi

java - JAXB - 复合模式和@XmlValue

转载 作者:数据小太阳 更新时间:2023-10-29 02:06:18 34 4
gpt4 key购买 nike

跟进JAXB and Composite Pattern ,我设法映射:

<precondition>
<or>
<and>
<just><query>foo</query></just>
<just><query>bar</query></just>
</and>
<just><query>baz</query></just>
</or>
</precondition>

但我想映射:

<precondition>
<or>
<and>
<query>foo</query>
<query>bar</query>
</and>
<query>baz</query>
</or>
</precondition>

我的 JAXB 类层次结构如下:

@XmlRootElement
@XmlSeeAlso({SimplePreconditionQuery.class, CompoundAndPreconditionQuery.class, CompoundOrPreconditionQuery.class})
public abstract class PreconditionQuery {
// JAXB does not deal with interfaces by default >:(
}

有几种查询:

@XmlSeeAlso(PreconditionQuery.class)
@XmlRootElement(name = "just")
public class SimplePreconditionQuery extends PreconditionQuery {

private String query;

@XmlElement(name = "query")
public String getQuery() {
return query;
}

public void setQuery(String query) {
this.query = query;
}
}

复合的 (AND/OR) 非常相似:

@XmlSeeAlso(PreconditionQuery.class)
@XmlRootElement(name = "and")
public class CompoundAndPreconditionQuery extends PreconditionQuery {

private Collection<PreconditionQuery> preconditionQueries = newArrayList();

@XmlElementRef(name = "query")
public Collection<PreconditionQuery> getPreconditionQueries() {
return preconditionQueries;
}

public void setPreconditionQueries(Collection<PreconditionQuery> preconditionQueries) {
this.preconditionQueries = preconditionQueries;
}
}

以及封闭的 bean:

public class Precondition {

private PreconditionQuery query;

@XmlElementRef(required = true)
public PreconditionQuery getQuery() {
return query;
}

public void setQuery(PreconditionQuery query) {
this.query = query;
}
}

JAXB 不允许我将 @XmlValue 映射到 SimplePreconditionQuery 上。为什么以及有什么选择?

最佳答案

问题

如果你只是这样做:

import javax.xml.bind.annotation.*;

@XmlRootElement(name = "query")
public class SimplePreconditionQuery extends PreconditionQuery {

private String query;

@XmlValue
public String getQuery() {
return query;
}

public void setQuery(String query) {
this.query = query;
}

}

您将得到以下异常,因为 SimplePreconditionQuery 子类不是 java.lang.Object

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
@XmlValue is not allowed on a class that derives another class.
this problem is related to the following location:
at public java.lang.String forum26714143.SimplePreconditionQuery.getQuery()
at forum26714143.SimplePreconditionQuery
at @javax.xml.bind.annotation.XmlSeeAlso(value=[class forum26714143.SimplePreconditionQuery, class forum26714143.CompoundAndPreconditionQuery, class forum26714143.CompoundOrPreconditionQuery])
at public forum26714143.PreconditionQuery forum26714143.Precondition.getQuery()
at forum26714143.Precondition

从继承层次结构中删除 PreconditionQuery

我们可以在类级别使用 @XmlTransient 注释从 JAXB 中删除该类。父类(super class)的所有属性都将被视为父类(super class)的属性。

import javax.xml.bind.annotation.*;

@XmlSeeAlso({SimplePreconditionQuery.class, CompoundAndPreconditionQuery.class, CompoundOrPreconditionQuery.class})
@XmlTransient
public abstract class PreconditionQuery {
// JAXB does not deal with interfaces by default >:(
}

现在我们得到以下异常:

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
Invalid @XmlElementRef : Type "class forum26714143.PreconditionQuery" or any of its subclasses are not known to this context.
this problem is related to the following location:
at public forum26714143.PreconditionQuery forum26714143.Precondition.getQuery()
at forum26714143.Precondition

让 JAXB 知道子类

现在我们已经从 JAXB 关心的类集中删除了 PreconditionQuery,我们现在不再受益于它包含的 @XmlSeeAlso 注释。因此,我们需要使我们的 @XmlElementRef 注释更加明确:

先决条件

import javax.xml.bind.annotation.*;

@XmlRootElement
public class Precondition {

private PreconditionQuery query;

@XmlElementRefs({
@XmlElementRef(name="and", type = CompoundAndPreconditionQuery.class),
@XmlElementRef(name="or", type= CompoundOrPreconditionQuery.class),
@XmlElementRef(name="query", type=SimplePreconditionQuery.class)
})
public PreconditionQuery getQuery() {
return query;
}

public void setQuery(PreconditionQuery query) {
this.query = query;
}

}

CompoundAndPreconditionQuery

您还需要为 CompoundAndPreconditionQueryCompoundAndPreconditionQuery 执行此操作。

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement(name = "and")
public class CompoundAndPreconditionQuery extends PreconditionQuery {

private Collection<PreconditionQuery> preconditionQueries = new ArrayList();

@XmlElementRefs({
@XmlElementRef(name="and", type = CompoundAndPreconditionQuery.class),
@XmlElementRef(name="or", type= CompoundOrPreconditionQuery.class),
@XmlElementRef(name="query", type=SimplePreconditionQuery.class)
})
public Collection<PreconditionQuery> getPreconditionQueries() {
return preconditionQueries;
}

public void setPreconditionQueries(Collection<PreconditionQuery> preconditionQueries) {
this.preconditionQueries = preconditionQueries;
}

}

处理接口(interface)

// JAXB does not deal with interfaces by default >:(

现在 JAXB 不再知道 Precondition 查询类,如果您愿意,可以将其设为接口(interface)。

public interface PreconditionQuery {

}

关于java - JAXB - 复合模式和@XmlValue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26714143/

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