Java JAXB MOXy编组和解编组对象的通用集合(包括字符串和基本包装器)
我面临使用MOXy对集合进行编组和解编组的问题。集合可以包含任何类型的元素。在下面的测试用例中,我尝试对字符串进行封送,然后取消封送 测试生成以下输出:Java JAXB MOXy编组和解编组对象的通用集合(包括字符串和基本包装器),java,collections,jaxb,moxy,xmlanyelement,Java,Collections,Jaxb,Moxy,Xmlanyelement,我面临使用MOXy对集合进行编组和解编组的问题。集合可以包含任何类型的元素。在下面的测试用例中,我尝试对字符串进行封送,然后取消封送 测试生成以下输出: Going with type: APPLICATION_XML Original XmlCollection: [one, two, three] Marshaled as application/xml: <?xml version="1.0" encoding="UTF-8"?><collection>onetwo
Going with type: APPLICATION_XML
Original XmlCollection: [one, two, three]
Marshaled as application/xml: <?xml version="1.0" encoding="UTF-8"?><collection>onetwothree</collection>
Unmarshaled XmlCollection: []
Going with type: APPLICATION_JSON
Original XmlCollection: [one, two, three]
Marshaled as application/json: {"value":["one","two","three"]}
Unmarshaled XmlCollection: []
使用类型:APPLICATION\u XML
原始XmlCollection:[一、二、三]
封送为application/xml:onetwother
取消签名的XmlCollection:[]
使用类型:APPLICATION_JSON
原始XmlCollection:[一、二、三]
封送为application/json:{“value”:[“一”、“二”、“三”]}
取消签名的XmlCollection:[]
在XML情况下,我希望集合元素被序列化为包含值的嵌套列表XML元素,但事实并非如此
在JSON的情况下,Generated代码看起来不错,但我希望对象能够正确地解组,但这并没有发生
当我使用SimpleObject集合(标记为Simple object的取消注释行)运行测试时,一切都像sharm一样工作,生成的输出如下:
Going with type: APPLICATION_XML
Original XmlCollection: [stringField='one', stringField='two', stringField='three']
Marshaled as application/xml: <?xml version="1.0" encoding="UTF-8"?><collection><simpleObject><stringField>one</stringField></simpleObject><simpleObject><stringField>two</stringField></simpleObject><simpleObject><stringField>three</stringField></simpleObject></collection>
Unmarshaled XmlCollection: [stringField='one', stringField='two', stringField='three']
Going with type: APPLICATION_JSON
Original XmlCollection: [stringField='one', stringField='two', stringField='three']
Marshaled as application/json: {"simpleObject":[{"stringField":"one"},{"stringField":"two"},{"stringField":"three"}]}
Unmarshaled XmlCollection: [stringField='one', stringField='two', stringField='three']
使用类型:APPLICATION\u XML
原始XmlCollection:[stringField='one',stringField='two',stringField='three']
封送为application/xml:onetwother
取消编组的XmlCollection:[stringField='one',stringField='two',stringField='three']
使用类型:APPLICATION_JSON
原始XmlCollection:[stringField='one',stringField='two',stringField='three']
封送为application/json:{“simpleObject”:[{“stringField”:“一”},{“stringField”:“两”},{“stringField”:“三”}]}
取消编组的XmlCollection:[stringField='one',stringField='two',stringField='three']
请理解为什么会发生这种情况以及必须如何正确进行映射的任何线索
测试用例:
public class TestCase {
// Element name holding value of primitive types
public static final String VALUE_ELEMENT = "value";
// Attribute prefix in JSON
public static final String ATTRIBUTE_PREFIX = "@";
public static void main(String... args) {
try {
for (MediaType type : new MediaType[]{MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) {
System.out.println("Going with type: " + type);
JAXBContext context = (JAXBContext) JAXBContextFactory.createContext(
new Class[]{
XmlCollection.class,
// Simple Object SimpleObject.class,
},
Collections.emptyMap());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, type);
marshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false);
marshaller.setProperty(MarshallerProperties.JSON_ATTRIBUTE_PREFIX, ATTRIBUTE_PREFIX);
marshaller.setProperty(MarshallerProperties.JSON_VALUE_WRAPPER, VALUE_ELEMENT);
marshaller.setProperty(UnmarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true);
XmlCollection original = new XmlCollection(Arrays.asList("one", "two", "three"));
// Simple object XmlCollection original = new XmlCollection(Arrays.asList(new SimpleObject("one"), new SimpleObject("two"), new SimpleObject("three")));
System.out.println("Original " + original.toString());
StreamResult result = new StreamResult(new StringWriter());
marshaller.marshal(original, result);
String generated = result.getWriter().toString();
System.out.println("Marshaled as " + type.getMediaType() + ": " + generated);
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, type);
unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false);
unmarshaller.setProperty(UnmarshallerProperties.JSON_ATTRIBUTE_PREFIX, ATTRIBUTE_PREFIX);
unmarshaller.setProperty(UnmarshallerProperties.JSON_VALUE_WRAPPER, VALUE_ELEMENT);
unmarshaller.setProperty(UnmarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true);
XmlCollection unmarshaled = unmarshaller.unmarshal(new StreamSource(new StringReader(generated)), XmlCollection.class).getValue();
System.out.println("Unmarshaled " + unmarshaled.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
@XmlRootElement(name = "collection")
@XmlAccessorType(XmlAccessType.FIELD)
public static class XmlCollection<T> {
@XmlAnyElement(lax = true)
private Collection collection = new ArrayList();
public XmlCollection() {
}
public XmlCollection(Collection<T> collection) {
this.collection.addAll(collection);
}
public Collection<T> getCollection() {
return collection;
}
@Override
public String toString() {
return "XmlCollection: " + collection;
}
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public static final class SimpleObject{
@XmlElement
public String stringField;
public SimpleObject(){}
public SimpleObject(String stringField){
this.stringField = stringField;
}
public String getStringField() {
return stringField;
}
public void setStringField(String stringField) {
this.stringField = stringField;
}
@Override
public String toString() {
return "stringField='" + stringField + '\'';
}
}
}
公共类测试用例{
//保存基元类型值的元素名
公共静态最终字符串值\u ELEMENT=“VALUE”;
//JSON中的属性前缀
公共静态最终字符串属性_PREFIX=“@”;
公共静态void main(字符串…参数){
试一试{
for(MediaType类型:newmediatype[]{MediaType.APPLICATION\uxml,MediaType.APPLICATION\ujson}){
System.out.println(“使用类型:“+type”);
JAXBContext上下文=(JAXBContext)JAXBContextFactory.createContext(
新类别[]{
XmlCollection.class,
//简单对象SimpleObject.class,
},
Collections.emptyMap());
Marshaller=context.createMarshaller();
setProperty(MarshallerProperties.MEDIA_类型,TYPE);
setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT,false);
setProperty(MarshallerProperties.JSON_ATTRIBUTE_PREFIX,ATTRIBUTE_PREFIX);
setProperty(MarshallerProperties.JSON_VALUE_包装,VALUE_元素);
setProperty(UnmarshallerProperties.JSON_包装器_作为_数组_名称,true);
XmlCollection original=新的XmlCollection(Arrays.asList(“一”、“二”、“三”);
//Simple object XmlCollection original=新的XmlCollection(Arrays.asList(新的SimpleObject(“一”)、新的SimpleObject(“两”)、新的SimpleObject(“三”);
System.out.println(“Original”+Original.toString());
StreamResult=新的StreamResult(新的StringWriter());
元帅。元帅(原件,结果);
生成的字符串=result.getWriter().toString();
System.out.println(“封送为“+type.getMediaType()+”:“+generated”);
Unmarshaller Unmarshaller=context.createUnmarshaller();
unmarshaller.setProperty(UnmarshallerProperties.MEDIA_类型,TYPE);
setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT,false);
unmarshaller.setProperty(UnmarshallerProperties.JSON_ATTRIBUTE_PREFIX,ATTRIBUTE_PREFIX);
setProperty(UnmarshallerProperties.JSON_VALUE_包装,VALUE_元素);
setProperty(UnmarshallerProperties.JSON_包装器_作为_数组_名称,true);
XmlCollection unmarshaled=unmarshaller.unmarshal(新StreamSource(新StringReader(已生成)),XmlCollection.class.getValue();
System.out.println(“Unmarshaled”+Unmarshaled.toString());
}
}捕获(例外e){
e、 printStackTrace();
}
}
@XmlRootElement(name=“collection”)
@XmlAccessorType(XmlAccessType.FIELD)
公共静态类XmlCollection{
@xmlanyement(lax=true)
private Collection=new ArrayList();
公共XmlCollection(){
}
公共XmlCollection(集合){
this.collection.addAll(collection);
}
公共集合getCollection(){
回收;
}
@凌驾
公共字符串toString(){
返回“XmlCollection:”+集合;
}
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
公共静态最终类SimpleObject{
@XmlElement
公共字符串字符串字段;
公共SimpleObject(){}
公共SimpleObject(字符串字符串字段){
this.stringField=stringField;
}
公共字符串getStringField(){
返回字符串字段;
}
公共无效设置字符串字段(字符串字符串字段){
this.stringField=stringField;
}
@凌驾
公共字符串toString(){
返回“stringField=”+stringField+“\”;
}
}
}