我想将一个不可变类型序列化为json和xml:
序列化的JSON就像:
{
"text" : "... the text..."
}
,序列化的xml就像:
<asText>_text_</asText>
(请注意,文本是xml的元素文本)
java对象如下:
@JsonRootName("asText")
@Accessors(prefix="_")
public static class AsText {
@JsonProperty("text") @JacksonXmlText
@Getter private final String _text;
public AsText(@JsonProperty("text") final String text) {
_text = text;
}
}
请注意_text属性是 final (因此对象是不可变的)并且使用@JacksonXmlText
进行注释,以便序列化为xml元素&#39; s文本
作为对象不可变,需要文本中的构造函数,构造函数的参数必须用@JsonProperty
注释
public AsText(@JsonProperty("text") final String text) {
_text = text;
}
对JSON进行序列化/反序列化时,一切正常 ...在向/从XML序列化/反序列化时出现问题:
// create the object
AsText obj = new AsText("_text_");
// init the mapper
XmlMapper mapper = new XmlMapper();
// write as xml
String xml = mapper.writeValueAsString(obj);
log.warn("Serialized Xml\n{}",xml);
// Read from xml
log.warn("Read from Xml:");
AsText objReadedFromXml = mapper.readValue(xml,
AsText.class);
log.warn("Obj readed from serialized xml: {}",
objReadedFromXml.getClass().getName());
例外是:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "" (class r01f.types.url.UrlQueryStringParam), not marked as ignorable (2 known properties: "value", "name"])
似乎xml模块需要对对象的构造函数进行注释,如:
public AsText(@JsonProperty("") final String text) {
_text = text;
}
但这甚至不起作用:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `test.types.SerializeAsXmlElementTextTest$AsText` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
需要在构造函数的参数中使用注释@JsonProperty("text")
来从JSON反序列化
......我怎样才能让它发挥作用
答案 0 :(得分:5)
尝试为该属性添加公共getter。我认为应该解决反序列化问题。
@JsonRootName("asText")
@Accessors(prefix = "_")
public static class AsText {
@JsonProperty("text")
@JacksonXmlText
@Getter
private final String _text;
public AsText(@JsonProperty("text") final String text) {
_text = text;
}
public String getText() {
return _text;
}
}
实际上,它的工作原理也没有添加吸气剂,这些版本的Lombak&amp;杰克逊。
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
</dependencies>
答案 1 :(得分:3)
我遇到了与错误相同的问题&#34;没有基于委托或属性的Creator&#34;。就我而言,它是Immutables版本2.5.6的问题。我通过降级到版本2.5.5修复了它。版本2.5.6在mvnrepository.com中可用,但在官方页面上是标记为2.5.5的稳定版本。
答案 2 :(得分:3)
更新2018年
这个hack在2.9.0中工作但似乎在commit之后停止工作。目前尚不清楚是否有一种简单的方法可以让它再次发挥作用。
看起来您的问题的主要原因是您尝试同时使用JSON和XML序列化但具有不同的配置。不幸的是,XmlMapper
继承自ObjectMapper
并继承了所有特定于JSON的配置(您可以覆盖它但不能使用特定于XML的注释清除它),这是您发生冲突的原因。似乎最简单的解决方法是在构造函数中使用@JsonAlias
注释。它有点hacky但它的工作原理。这是一个适合我的最小例子(没有Lombok):
@JsonRootName("asText")
public static class AsText {
@JsonProperty("text")
@JacksonXmlText
private final String _text;
public AsText(@JsonAlias("") @JsonProperty("text") final String text) {
_text = text;
}
@JsonIgnore
public String getText() {
return _text;
}
@Override
public String toString() {
return "AsText{" +
"_text='" + _text + '\'' +
'}';
}
}
请注意,我还在getter中添加了@JsonIgnore
,因为我没有获得您请求的XML格式(并且您可以使用onX中描述的Lombok的onMethod
执行相同操作
进行简单的测试:
public static void main(String[] args) throws IOException {
// create the object
AsText obj = new AsText("123_text_");
// init the mapper
//ObjectMapper mapper = new ObjectMapper();
XmlMapper mapper = new XmlMapper();
// write as xml
String xml = mapper.writeValueAsString(obj);
System.out.println("Serialized Xml\n" + xml);
// Read from xml
AsText objReadedFromXml = mapper.readValue(xml, AsText.class);
System.out.println("Read from Xml: " + objReadedFromXml);
}
我得到以下输出:
序列化Xml
&lt; asText&gt; 123_text_&lt; / asText&gt;
从Xml读取:AsText {_text ='123_text _'}