JAXB/MOXy能否以与常规类(非枚举)相同的方式序列化枚举?

JAXB/MOXy能否以与常规类(非枚举)相同的方式序列化枚举?,jaxb,moxy,Jaxb,Moxy,假设我对enum的定义如下: public enum ArchiveStatus implements Serializable { CANDIDATE (0, "CANDIDATE", "Candidate for archival"), IN_LIBRARY (1, "IN-LIBRARY", ".."), FROM_LIBRARY (2, "FROM-LIBRARY", ".."); private int id; pr

假设我对enum的定义如下:

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() { .. }
}
{
   ..
   "archiveStatus": "CANDIDATE",
   ..
}
默认情况下,MOXy会将其序列化为JSON,如下所示:

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() { .. }
}
{
   ..
   "archiveStatus": "CANDIDATE",
   ..
}
是否有方法将MOXy(在映射文件中)配置为像常规类一样序列化枚举:

{
   ..
   "archiveStatus": { "id" : 0, "shortName": "CANDIDATE", "longName": "Candidate for archival" },
   ..
}

注意:我是专家组的负责人和成员

ArchiveStatus适配器

您可以通过利用
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;
    }

}
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);
    }

}
了解更多信息


这样做有什么意义?唯一标识枚举元素所需的唯一信息是名称。唯一的原因是保留返回JSON的API。我正在调查,看看是否可以使用MOXy来取代自行开发的JSON序列化程序。