想象一下,我的枚举定义如下:
public enum ArchiveStatus implements Serializable {
CANDIDATE (0, "CANDIDATE", "Candidate for archival"),
IN_LIBRARY (1, "IN-LIBRARY", ".."),
FROM_LIBRARY (2, "FROM-LIBRARY", "..");
private int id;
private String shortName;
private String longName;
public ArchiveStatus( int id, String shortName, String longName ) {
..
}
public int getId() { .. }
public String getShortName() { .. }
public String getLongName() { .. }
}
默认情况下,MOXy会将其序列化为JSON,如下所示:
{
..
"archiveStatus": "CANDIDATE",
..
}
有没有办法配置MOXy(在映射文件中)像常规类一样序列化枚举:
{
..
"archiveStatus": { "id" : 0, "shortName": "CANDIDATE", "longName": "Candidate for archival" },
..
}
答案 0 :(得分:4)
注意:我是EclipseLink JAXB (MOXy)主管,是JAXB 2 (JSR-222)专家组的成员。
<强> ArchiveStatusAdapter 强>
您可以通过利用XmlAdapter
来解决此用例。 XmlAdapter
是一种JAXB机制,允许您将一种类型的对象编组为另一种。
package forum10144489;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class ArchiveStatusAdapter extends XmlAdapter<ArchiveStatusAdapter.AdaptedArchiveStatus, ArchiveStatus> {
public static class AdaptedArchiveStatus {
public int id;
public String shortName;
public String longName;
}
@Override
public ArchiveStatus unmarshal(AdaptedArchiveStatus adaptedArchiveStatus) throws Exception {
if(null == adaptedArchiveStatus) {
return null;
}
return ArchiveStatus.valueOf(adaptedArchiveStatus.shortName);
}
@Override
public AdaptedArchiveStatus marshal(ArchiveStatus archiveStatus) throws Exception {
if(null == archiveStatus) {
return null;
}
AdaptedArchiveStatus adaptedArchiveStatus = new AdaptedArchiveStatus();
adaptedArchiveStatus.id = archiveStatus.getId();
adaptedArchiveStatus.longName = archiveStatus.getLongName();
adaptedArchiveStatus.shortName = archiveStatus.getShortName();
return adaptedArchiveStatus;
}
}
<强>根强>
可以使用XmlAdapter
注释在字段,属性,类型或包级别指定@XmlJavaTypeAdapter
。
package forum10144489;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
public class Root {
private ArchiveStatus archiveStatus;
@XmlJavaTypeAdapter(ArchiveStatusAdapter.class)
public ArchiveStatus getArchiveStatus() {
return archiveStatus;
}
public void setArchiveStatus(ArchiveStatus archiveStatus) {
this.archiveStatus = archiveStatus;
}
}
<强> jaxb.properties 强>
要将MOXy指定为JAXB提供程序,您需要在与域类相同的程序包中添加名为jaxb.properties
的文件,并使用以下条目。
javax.xml.bind.context.factory = org.eclipse.persistence.jaxb.JAXBContextFactory
<强>演示强>
package forum10144489;
import java.io.StringReader;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String, Object> properties = new HashMap<String, Object>(2);
properties.put("eclipselink.media-type", "application/json");
properties.put("eclipselink.json.include-root", false);
JAXBContext jc = JAXBContext.newInstance(new Class[] {Root.class}, properties);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StringReader jsonStringReader = new StringReader("{\"archiveStatus\" : {\"id\" : 0, \"shortName\" : \"CANDIDATE\", \"longName\" : \"Candidate for archival\"}}");
StreamSource jsonSource = new StreamSource(jsonStringReader);
Root root = unmarshaller.unmarshal(jsonSource, Root.class).getValue();
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}
<强>输出强>
以下是运行演示代码的输出:
{
"archiveStatus" : {
"id" : 0,
"shortName" : "CANDIDATE",
"longName" : "Candidate for archival"
}
}
了解更多信息