Reputation: 33618
I parse an xml file and want to have 2 setters for integer property:
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(name = "")
@XmlRootElement(name = "request")
public class Request {
private Integer intTag;
@XmlElement(required = true, name = "intTag", nillable = true)
public Integer getIntTag () {
return intTag;
}
@XmlElement(required = true, name = "intTag", nillable = true)
public void setIntTag (String intTag) {
if (StringUtils.isBlank(intTag)) {
this.intTag = null;
} else {
this.intTag = Integer.parseInt(intTag);
}
}
public void setIntTag (Integer intTag) {
this.intTag = intTag;
}
}
I annotate setIntTag(String) but Jaxb marchaller calls setIntTag(Integer) and pass Integer to it, if I delete setIntTag(Integer), marchaller calls the string setter.
How annotate these methods to keep both setters, and tell marshaller use string setter?
Upvotes: 1
Views: 1814
Reputation: 22027
I believe it's a kind of expected behaviors.
JAXB will work on those two methods by Java Beans convention
T getXxx();
void setXxx(T xxx);
If you want to none nil but empty
string as nil
, you can make an XmlAdapter
.
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "request")
public class Request {
private static class EmtpyStringAdapter
extends XmlAdapter<String, Integer> {
@Override
public Integer unmarshal(final String value) throws Exception {
if (value == null || value.isEmpty()) {
return null;
}
return Integer.valueOf(value);
}
@Override
public String marshal(final Integer bound) throws Exception {
if (bound == null) {
return null;
}
return bound.toString();
}
}
public static void main(final String[] args) throws JAXBException {
final JAXBContext context = JAXBContext.newInstance(Request.class);
{
final Request request1 = new Request();
request1.setIntTag(0);
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
final Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
Boolean.TRUE);
marshaller.marshal(request1, System.out);
marshaller.marshal(request1, buffer);
final Unmarshaller unamrshaller = context.createUnmarshaller();
final Request request2 = (Request) unamrshaller.unmarshal(
new ByteArrayInputStream(buffer.toByteArray()));
System.out.println(request2.getIntTag());
}
{
final Request request1 = new Request();
request1.setIntTag(null);
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
final Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
Boolean.TRUE);
marshaller.marshal(request1, System.out);
marshaller.marshal(request1, buffer);
final Unmarshaller unamrshaller = context.createUnmarshaller();
final Request request2 = (Request) unamrshaller.unmarshal(
new ByteArrayInputStream(buffer.toByteArray()));
System.out.println(request2.getIntTag());
}
{
final String xml = "<request><intTag></intTag></request>";
final Unmarshaller unamrshaller = context.createUnmarshaller();
final Request request2 =
(Request) unamrshaller.unmarshal(new StringReader(xml));
System.out.println(request2.getIntTag());
}
}
@XmlElement(nillable = true, required = true)
@XmlJavaTypeAdapter(EmtpyStringAdapter.class)
public Integer getIntTag() {
return intTag;
}
public void setIntTag(Integer intTag) {
this.intTag = intTag;
}
private Integer intTag;
}
Prints
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<request>
<intTag>0</intTag>
</request>
0
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<request>
<intTag xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</request>
null
<request><intTag></intTag></request>
null
Upvotes: 1