我有一个名为a
的布尔字段和两个方法void setA(String a)
和boolean isA()
。我已设置@XmlAccessorType(XmlAccessType.NONE)
并使用@XmlAttribute
作为设置者。
因为getter返回一个布尔值,但是setter期望一个字符串JAX-B只是忽略了这个setter。这是代码中各种错误的原因,因为布尔值设置不正确,调试非常烦人。
有没有办法告诉JAX-B使用setter?为什么JAX-B完全被getter方法搞糊涂了,我使用XmlAccessType.NONE
会阻止所有隐式解释?
如果出现这样一个星座,计划B将让JAX-B失败,但是如何做到这一点?
感谢任何提示: - )
答案 0 :(得分:3)
鉴于你已经在使用XmlAccessorType注释,我猜你已经知道你可以使用@XmlAccessType.FIELD
并让JAXB在决定编组/解组的时候查看类字段而不是setter方法?
对于您当前的配置,您可能在setter方法上有@XmlElement
注释,其中数据类型错误,如提及的评论者所述。从你的问题中不清楚你为什么需要setA取一个String而不是boolean参数,但如果你可以在setter上将类型更改为boolean,那么这也有效。
编辑:
根据您在下面的评论,您似乎有两种选择:
撰写@XmlAdapter
或
为字符串字段创建一个setter / getter对,为一个计算字段创建一个isA(这是我一直这样做的方式,因为它看起来有点简单):
String a;
void setA(String);
String getA();
// calcualted field:
boolean isA() {
// or whatever your real implementation is
return a.equals("yes");
}
答案 1 :(得分:2)
我建议Kevin建议使用@XmlAccessType.FIELD
并结合XmlAdapter
来获取您正在寻找的行为:
<强>根强>
要使此示例与JAXB-RI一起使用,我需要创建Boolean
类型的字段。如果您使用的是EclipseLink JAXB (MOXy),则可以填写boolean
字段。
package forum7876493;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Root {
@XmlAttribute
@XmlJavaTypeAdapter(BooleanAdapter.class)
private Boolean a;
public boolean isA() {
return a;
}
public void setA(String s) {
this.a = "yes".equals(s) || "on".equals(s) || "in".equals(s);
}
}
<强> BooleanAdapter 强>
XmlAdapter
是您可以在setA(String)
方法中添加逻辑的地方。
package forum7876493;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class BooleanAdapter extends XmlAdapter<String, Boolean> {
@Override
public Boolean unmarshal(String s) throws Exception {
return "yes".equals(s) || "on".equals(s) || "in".equals(s);
}
@Override
public String marshal(Boolean b) throws Exception {
if(b) {
return "yes";
}
return "no";
}
}
<强>演示强>
package forum7876493;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Root root = (Root) unmarshaller.unmarshal(new File("src/forum7876493/input.xml"));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
<强> input.xml中强>
<?xml version="1.0" encoding="UTF-8"?>
<root a="on"/>
<强>输出强>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root a="yes"/>
<强>更新强>
或者,您可以为String
属性引入a
getter。您需要将isA()
方法设为@XmlTransient
:
package forum7876493;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement
public class Root {
private boolean a;
@XmlTransient
public boolean isA() {
return a;
}
@XmlAttribute
public String getA() {
if(a) {
return "yes";
}
return "no";
}
public void setA(String s) {
this.a = "yes".equals(s) || "on".equals(s) || "in".equals(s);
}
}