I have this bean
@XmlRootElement
class Test {
boolean someValue;
List<Field> fields;
}
I would like to serialize it as
<fields>
<field>
<name>someValue</name>
<value>...</value>
</field>
</fields>
<fields>
<field>
<name>otherValue</name>
<value>...</value>
</field>
</fields>
(or as json)
How should I do that, preferrably using jaxb annotations?
I'm using jersey, but the answer doens't have to be specific to it.
How about the following?
Using EclipseLink JAXB (MOXy) you could do the following. Note: I'm the MOXy tech lead.
Test
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement
@XmlType(propOrder={"someValue", "fields"})
@XmlAccessorType(XmlAccessType.FIELD)
class Test {
@XmlJavaTypeAdapter(SomeValueAdapter.class)
@XmlPath("fields[1]")
boolean someValue;
@XmlJavaTypeAdapter(FieldsAdapter.class)
List<Field> fields = new ArrayList<Field>();
public Boolean isSomeValue() {
return someValue;
}
public void setSomeValue(boolean someValue) {
this.someValue = someValue;
}
public List<Field> getFields() {
return fields;
}
public void setFields(List<Field> fields) {
this.fields = fields;
}
public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
for(Field field : fields) {
if("someValue".equals(field.getName())) {
someValue = Boolean.valueOf(field.getValue());
fields.remove(field);
}
}
}
}
Field
public class Field {
private String name;
private String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
SomeValueAdapter
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class SomeValueAdapter extends XmlAdapter<AdaptedField, Boolean> {
@Override
public Boolean unmarshal(AdaptedField v) throws Exception {
String value = v.getField().getValue();
return Boolean.valueOf(value);
}
@Override
public AdaptedField marshal(Boolean v) throws Exception {
AdaptedField adaptedField = new AdaptedField();
Field field = new Field();
field.setName("someValue");
field.setValue(String.valueOf(v));
adaptedField.setField(field);
return adaptedField;
}
}
FieldsAdapter
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class FieldsAdapter extends XmlAdapter<AdaptedField, Field> {
@Override
public Field unmarshal(AdaptedField v) throws Exception {
return v.getField();
}
@Override
public AdaptedField marshal(Field v) throws Exception {
AdaptedField adaptedField = new AdaptedField();
adaptedField.setField(v);
return adaptedField;
}
}
AdaptedField
public class AdaptedField {
private Field field;
public Field getField() {
return field;
}
public void setField(Field field) {
this.field = field;
}
}
Demo
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(Test.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Test test = (Test) unmarshaller.unmarshal(new File("input.xml"));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(test, System.out);
}
}
input.xml
<?xml version="1.0" encoding="UTF-8"?>
<test>
<fields>
<field>
<name>someValue</name>
<value>true</value>
</field>
</fields>
<fields>
<field>
<name>otherValue</name>
<value>1</value>
</field>
</fields>
<fields>
<field>
<name>anotherValue</name>
<value>2</value>
</field>
</fields>
</test>
For More Information