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异常){
//一些处理
}
}