Jacksonライブラリを使用してJAXBアノテーションを使用してJavaオブジェクトをXMLにシリアル化しようとしていますが、XML出力をきれいに印刷する際に問題が発生します。
これが私のサンプルコードの使用法です:
ObjectMapper mapper = new XmlMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
String xml = mapper.writeValueAsString(person);
そして、私は以下の例外を見ています。ここでの問題は、JacksonがStax2WriterをXMLライターとして使用し、Stax2が生の文字列の書き込みをサポートしていないようです(この場合、DefaultPrettyPrinterは「\ n」を生の文字列として書き込もうとします)。
com.fasterxml.jackson.databind.JsonMappingException: Not implemented (through reference chain: xml.serialization.jackson.dto.Person["name"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.Java:232)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.Java:197)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.Java:187)
at com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializer.serializeFields(XmlBeanSerializer.Java:174)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.Java:152)
at com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider.serializeValue(XmlSerializerProvider.Java:92)
at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.Java:2818)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.Java:2275)
at xml.serialization.jackson.SerializationTest.main(SerializationTest.Java:46)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:57)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
at Java.lang.reflect.Method.invoke(Method.Java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.Java:120)
Caused by: Java.lang.UnsupportedOperationException: Not implemented
at org.codehaus.stax2.ri.Stax2WriterAdapter.writeRaw(Stax2WriterAdapter.Java:380)
at org.codehaus.stax2.ri.Stax2WriterAdapter.writeRaw(Stax2WriterAdapter.Java:373)
at com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter$Lf2SpacesIndenter.writeIndentation(DefaultXmlPrettyPrinter.Java:498)
at com.fasterxml.jackson.dataformat.xml.util.DefaultXmlPrettyPrinter.writeLeafElement(DefaultXmlPrettyPrinter.Java:271)
at com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator.writeString(ToXmlGenerator.Java:489)
at com.fasterxml.jackson.databind.ser.std.StringSerializer.serialize(StringSerializer.Java:39)
at com.fasterxml.jackson.databind.ser.std.StringSerializer.serialize(StringSerializer.Java:21)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.Java:541)
at com.fasterxml.jackson.dataformat.xml.ser.XmlBeanSerializer.serializeFields(XmlBeanSerializer.Java:161)
... 10 more
それを回避する方法について何か考えはありますか?
Stax2WriterAdapterのドキュメントによると、デフォルトの実装は不完全です。また、コード内のコメントによると、writeRaw()メソッドは、JavaランタイムのデフォルトであるStax1.0を使用して実装することはできません。
このwikiページ で提案されているように、Stax2ライブラリを使用するように切り替える必要があります。
次のMaven依存関係をプロジェクトに追加した後、以下の例が期待どおりに機能し始めました。
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>woodstox-core-asl</artifactId>
<version>4.1.4</version>
</dependency>
コード例:
public class JacksonXmlMapper {
public static class Person {
final public String name;
public Person(String name) {
this.name = name;
}
}
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new XmlMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
System.out.println(mapper.writeValueAsString(new Person("John")));
}
}
出力:
<Person>
<name>John</name>
</Person>