Java 是否使用Jackson将列表序列化为xml而不使用注释?

Java 是否使用Jackson将列表序列化为xml而不使用注释?,java,xml,generics,collections,jackson,Java,Xml,Generics,Collections,Jackson,我正在寻找一种方法来(反)序列化列表,而不使用Jackson中的注释。这可能吗?到目前为止,我所做的是尝试将-标记替换为一个说明项目类的标记,但没有效果。即使这样做有效,我也不确定杰克逊是否会提供一种处理标签信息的方法 为了更好地了解我的目标,这里有一个示例: public class JacksonTest { private static class ListElement { private boolean value; // getters, s

我正在寻找一种方法来(反)序列化
列表
,而不使用Jackson中的注释。这可能吗?到目前为止,我所做的是尝试将
-标记替换为一个说明项目类的标记,但没有效果。即使这样做有效,我也不确定杰克逊是否会提供一种处理标签信息的方法

为了更好地了解我的目标,这里有一个示例:

public class JacksonTest {

    private static class ListElement {
        private boolean value;
        // getters, setters, constructors omitted
    }

    @Test
    public void testDeSerialization() throws Exception {
        final List<ListElement> existing = Arrays.asList(new ListElement(true));
        final ObjectMapper mapper = new XmlMapper();
        final JavaType listJavaType = mapper.getTypeFactory().constructCollectionType(List.class, ListElement.class);
        final String listString = mapper.writerFor(listJavaType).writeValueAsString(existing);
        System.out.println(listString);
        // "<List><item><value>true</value></item></List>"
    }

}
公共类JacksonTest{
私有静态类ListElement{
私有布尔值;
//省略了getter、setter和构造函数
}
@试验
public void testDeSerialization()引发异常{
final List existing=Arrays.asList(new listlement(true));
final ObjectMapper mapper=new XmlMapper();
final JavaType listJavaType=mapper.getTypeFactory().constructCollectionType(List.class,ListElement.class);
最终字符串listString=mapper.writerFor(listJavaType).writeValueAsString(现有);
System.out.println(listString);
//“对”
}
}
因此,结果是
true
,而我希望将
-标记替换为(限定的)类名或提供
类型
-属性。 当然,如果Jackson无法处理这个类名,即使这样也不会有帮助


我是已经走到了死胡同还是还有路要走?

您可以定义自己的JsonSerializer(也用于XML)并将其添加到JacksonXmlModule中

ToXmlGenerator有一个setNextName函数,允许您覆盖默认项名称

private class MyListSerializer extends JsonSerializer<List> {
    @Override
    public void serialize(List list, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException {
        for (Object obj : list) {
            if (jsonGenerator instanceof ToXmlGenerator) {
                ToXmlGenerator xmlGenerator = (ToXmlGenerator) jsonGenerator;
                String className = obj.getClass().getSimpleName();
                xmlGenerator.setNextName(new QName(className));
            }
            jsonGenerator.writeObject(obj);
            // this is overridden at the next iteration
            // and ignored at the last
            jsonGenerator.writeFieldName("dummy");
        }
    }

    @Override
    public Class<List> handledType() {
        return List.class;
    }
}

@Test
public void testDeSerialization() throws Exception {
    final List<ListElement> existing = Arrays.asList(new ListElement(true));
    JacksonXmlModule module = new JacksonXmlModule();
    module.addSerializer(new MyListSerializer());
    final ObjectMapper mapper = new XmlMapper(module);
    final JavaType listJavaType = mapper.getTypeFactory().constructCollectionType(List.class, ListElement.class);
    final ObjectWriter writer = mapper.writerFor(listJavaType);
    final String listString = writer.writeValueAsString(existing);
    System.out.println(listString);
    // "<List><ListElement><value>true</value></ListElement></List>"
}
私有类MyListSerializer扩展JsonSerializer{
@凌驾
public void serialize(列表列表、JsonGenerator JsonGenerator、SerializerProvider SerializerProvider)
抛出IOException{
对于(对象对象:列表){
if(jsonGenerator实例OxmlGenerator){
ToXmlGenerator xmlGenerator=(ToXmlGenerator)jsonGenerator;
字符串className=obj.getClass().getSimpleName();
setNextName(新的QName(className));
}
jsonGenerator.writeObject(obj);
//这将在下一次迭代中被覆盖
//最后被忽视了
jsonGenerator.writeFieldName(“虚拟”);
}
}
@凌驾
公共类handledType(){
返回列表.class;
}
}
@试验
public void testDeSerialization()引发异常{
final List existing=Arrays.asList(new listlement(true));
JacksonXmlModule模块=新的JacksonXmlModule();
addSerializer(新的MyListSerializer());
最终ObjectMapper映射器=新的XmlMapper(模块);
final JavaType listJavaType=mapper.getTypeFactory().constructCollectionType(List.class,ListElement.class);
final ObjectWriter writer=mapper.writer(listJavaType);
最终字符串listString=writer.writeValueAsString(现有);
System.out.println(listString);
//“对”
}

好的,在对Evertude的建议进行了一些修补和调试之后,我找到了一个解决方案。我对序列化部分不是很满意,老实说,我不知道我为什么要这样做。调试时,我注意到需要调用一次
XmlGenerator::setNextName
,但对下一次调用没有任何影响,因此我必须在那里实现一个开关,并直接为循环中的下一项设置字段名

如果有人知道我做错了什么,我会很高兴,但至少我的尝试现在起作用了:

@Test
public void testDeSerialization() throws Exception {
    final List<ListElement> existing = Arrays.asList(new ListElement(true), new ListElement(false));
    JacksonXmlModule module = new JacksonXmlModule();
    module.addSerializer(new MyListSerializer());
    final ObjectMapper mapper = new XmlMapper(module);
    final JavaType listJavaType = mapper.getTypeFactory().constructCollectionType(List.class, ListElement.class);
    final ObjectWriter writer = mapper.writerFor(listJavaType);
    final String listString = writer.writeValueAsString(existing);
    module.addDeserializer(List.class, new MyListDeserializer());
    List<ListElement> deserialized = mapper.readValue(listString, List.class);
    assertEquals(existing, deserialized); // provided there're proper hash() and equals() methods
}

private class MyListSerializer extends JsonSerializer<List> {

    @Override
    public void serialize(List list, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException {
        boolean done = false;
        for (Object obj : list) {
            if (jsonGenerator instanceof ToXmlGenerator) {
                ToXmlGenerator xmlGenerator = (ToXmlGenerator) jsonGenerator;
                String className = obj.getClass().getSimpleName();
                // weird switch
                if (!done) xmlGenerator.setNextName(new QName(className));
                else jsonGenerator.writeFieldName(className);
                done = true;
            }
            jsonGenerator.writeObject(obj);
        }
    }

    @Override
    public Class<List> handledType() {
        return List.class;
    }
}

private class MyListDeserializer extends JsonDeserializer<List> {

    @Override
    public List deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        List<Object> items = new ArrayList<>();
        JsonToken nextToken;
        while ((nextToken = p.nextToken()) != JsonToken.END_OBJECT) {
            String currentName = p.currentName();
            try {
                String className = "my.test.project.JacksonCustomSerializer$" + currentName;
                Class<?> loadClass = getClass().getClassLoader().loadClass(className);
                p.nextToken();
                items.add(p.readValueAs(loadClass));
            } catch (ClassNotFoundException e) {
                // some handling
            }
        }
        return items;
    }

    @Override
    public Class<List> handledType() {
        return List.class;
    }
}
@测试
public void testDeSerialization()引发异常{
final List existing=Arrays.asList(新ListElement(true)、新ListElement(false));
JacksonXmlModule模块=新的JacksonXmlModule();
addSerializer(新的MyListSerializer());
最终ObjectMapper映射器=新的XmlMapper(模块);
final JavaType listJavaType=mapper.getTypeFactory().constructCollectionType(List.class,ListElement.class);
final ObjectWriter writer=mapper.writer(listJavaType);
最终字符串listString=writer.writeValueAsString(现有);
module.addDeserializer(List.class,新的MyListDeserializer());
List反序列化=mapper.readValue(listString,List.class);
assertEquals(现有的,反序列化的);//只要有适当的hash()和equals()方法
}
私有类MyListSerializer扩展JsonSerializer{
@凌驾
public void serialize(列表列表、JsonGenerator JsonGenerator、SerializerProvider SerializerProvider)
抛出IOException{
布尔完成=假;
对于(对象对象:列表){
if(jsonGenerator实例OxmlGenerator){
ToXmlGenerator xmlGenerator=(ToXmlGenerator)jsonGenerator;
字符串className=obj.getClass().getSimpleName();
//奇怪的开关
if(!done)xmlGenerator.setNextName(新的QName(className));
else jsonGenerator.writeFieldName(类名称);
完成=正确;
}
jsonGenerator.writeObject(obj);
}
}
@凌驾
公共类handledType(){
返回列表.class;
}
}
私有类MyListDeserializer扩展了JsonDeserializer{
@凌驾
公共列表反序列化(JsonParser p,DeserializationContext ctxt)抛出IOException,JsonProcessingException{
列表项=新建ArrayList();
杰森托肯·奈克托肯;
while((nextToken=p.nextToken())!=JsonToken.END\u对象){
字符串currentName=p.currentName();
试一试{
String className=“my.test.project.JacksonCustomSerializer$”+currentName;
类loadClass=getClass().getClassLoader().loadClass(类名);
p、 nextToken();
添加(p.readValueAs(loadClass));
}catch(classnotfounde异常){
//一些处理
}
}