gpt4 book ai didi

java - 多个 Jackson XML 自定义 (XMLStreamWriter) 序列化程序抛出异常

转载 作者:行者123 更新时间:2023-12-04 15:42:39 25 4
gpt4 key购买 nike

如果一个类中有多个自定义 XML 序列化程序 ( XMLStreamWriter ),序列化将失败。

我有两个类(class):CustomClass1 , CustomClass2 .有一个包装类TestJacksonXml1 .当我尝试序列化 TestJacksonXml1 时,它抛出异常。

自定义类1

class CustomClass1 {
int prop1;

public CustomClass1(int prop1) {
this.prop1 = prop1;
}

public int getProp1() {
return prop1;
}

static class CustomClass1Serializer extends StdSerializer<CustomClass1> {
public CustomClass1Serializer() { this(null); }

public CustomClass1Serializer(Class<CustomClass1> t) {
super(t);
}

@Override
public void serialize(CustomClass1 customClass1, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
final ToXmlGenerator toXmlGenerator = (ToXmlGenerator) jsonGenerator;
final XMLStreamWriter staxWriter = (toXmlGenerator).getStaxWriter();
try {
staxWriter.writeStartElement("class1");
staxWriter.writeCharacters(String.valueOf(customClass1.prop1));
staxWriter.writeEndElement();
} catch (XMLStreamException e){
e.printStackTrace();
}
}
}
}

自定义类2
class CustomClass2 {
int prop2;

public CustomClass2(int prop2) {
this.prop2 = prop2;
}

public int getProp2() {
return prop2;
}

static class CustomClass2Serializer extends StdSerializer<CustomClass2> {
public CustomClass2Serializer() { this(null); }

public CustomClass2Serializer(Class<CustomClass2> t) {
super(t);
}

@Override
public void serialize(CustomClass2 customClass2, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
final ToXmlGenerator toXmlGenerator = (ToXmlGenerator) jsonGenerator;
final XMLStreamWriter staxWriter = (toXmlGenerator).getStaxWriter();
try {
staxWriter.writeStartElement("class2");
staxWriter.writeCharacters(String.valueOf(customClass2.prop2));
staxWriter.writeEndElement();
} catch (XMLStreamException e){
e.printStackTrace();
}
}
}
}

封闭类
public class TestJacksonXml1 {
@JsonSerialize(using = CustomClass1.CustomClass1Serializer.class)
CustomClass1 obj1;

@JsonSerialize(using = CustomClass2.CustomClass2Serializer.class)
CustomClass2 obj2;

public TestJacksonXml1(CustomClass1 obj1, CustomClass2 obj2) {
this.obj1 = obj1;
this.obj2 = obj2;
}

public CustomClass1 getObj1() {
return obj1;
}

public CustomClass2 getObj2() {
return obj2;
}

public static void main(String[] args) throws JsonProcessingException {
XmlMapper xmlMapper = new XmlMapper();
System.out.println(xmlMapper.writeValueAsString(new TestJacksonXml1(new CustomClass1(10), new CustomClass2(20))));
}
}

我得到的异常(exception)是
Exception in thread "main" com.fasterxml.jackson.core.JsonGenerationException: Can not write a field name, expecting a value
at com.fasterxml.jackson.core.JsonGenerator._reportError(JsonGenerator.java:1961)
at com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.writeFieldName(ToXmlGenerator.java:435)
at com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.writeFieldName(ToXmlGenerator.java:577)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:725)
at com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializerBase.serializeFields(XmlBeanSerializerBase.java:202)
at com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializer.serialize(XmlBeanSerializer.java:117)
at com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider.serializeValue(XmlSerializerProvider.java:107)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3905)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3219)
at fk.reportsvc.common.TestJacksonXml1.main(TestJacksonXml1.java:39)

当我注释掉一个自定义序列化程序时,另一个可以工作。为什么会这样?

我们不应该一次使用两个/多个自定义序列化程序(使用 XMLStreamWriter )吗?

如果我使用 JsonGenerator直接代替 XMLStreamWriter ,然后我就可以同时使用两个自定义序列化程序。

PS:我的实际业务类包含许多要转换为嵌套 XML 元素和属性的字段。因此更喜欢 XMLStreamWriter直接超过其他人。

最佳答案

使用来自 ToXmlGenerator 的方法要简单得多。类(class)。看看:setNextName , writeRawwriteRepeatedFieldName方法。在您的情况下,实现可能如下所示:

class CustomClass2Serializer extends StdSerializer<CustomClass2> {

private final QName name = new QName("class2");

public CustomClass2Serializer() {
super(CustomClass2.class);
}

@Override
public void serialize(CustomClass2 customClass2, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
final ToXmlGenerator xmlGenerator = (ToXmlGenerator) jsonGenerator;
xmlGenerator.setNextName(name);
xmlGenerator.writeStartObject();
xmlGenerator.writeRaw(String.valueOf(customClass2.prop2));
xmlGenerator.writeRepeatedFieldName();
xmlGenerator.writeEndObject();
}
}

和:
class CustomClass1Serializer extends StdSerializer<CustomClass1> {

private final QName name = new QName("class1");

public CustomClass1Serializer() {
super(CustomClass1.class);
}

@Override
public void serialize(CustomClass1 customClass1, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
final ToXmlGenerator xmlGenerator = (ToXmlGenerator) jsonGenerator;
xmlGenerator.setNextName(name);
xmlGenerator.writeStartObject();
xmlGenerator.writeRaw(String.valueOf(customClass1.prop1));
xmlGenerator.writeRepeatedFieldName();
xmlGenerator.writeEndObject();
}
}

已生成 XML应该如下所示:
<TestJacksonXml1>
<class1>10</class1>
<class2>20</class2>
</TestJacksonXml1>

您的情况的主要问题是您想跳过 object CustomClass1 的节点和 CustomClass1类。为 TestJacksonXml1 实现序列化器要简单得多。类(class):
class TestJacksonXml1JsonSerializer extends JsonSerializer<TestJacksonXml1> {
@Override
public void serialize(TestJacksonXml1 value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
gen.writeStringField("class1", String.valueOf(value.obj1.prop1));
gen.writeStringField("class2", String.valueOf(value.obj2.prop2));
gen.writeEndObject();
}
}

现在,TestJacksonXml1 类应如下所示:
@JsonSerialize(using = TestJacksonXml1JsonSerializer.class)
class TestJacksonXml1 {

CustomClass1 obj1;
CustomClass2 obj2;
// getters, setters, etc
}

它应该生成相同的输出,但更容易实现。

关于java - 多个 Jackson XML 自定义 (XMLStreamWriter) 序列化程序抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57275271/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com