Java ObjectMapper.writeValueAsString的输出中存在重复值
我正在使用JacksonJava ObjectMapper.writeValueAsString的输出中存在重复值,java,json,serialization,jackson,polymorphism,Java,Json,Serialization,Jackson,Polymorphism,我正在使用JacksonObjectMapper对具有多态嵌套类的类进行(反)序列化。JSON到类的反序列化工作正常,但是当我尝试使用writeValueAsString函数将类序列化为JSON时,我发现输出中存在重复的值 public class Movie { private String movieName; @JsonTypeInfo(use=Id.NAME,include=As.EXTERNAL_PROPERTY,property="movieName")
ObjectMapper
对具有多态嵌套类的类进行(反)序列化。JSON到类的反序列化工作正常,但是当我尝试使用writeValueAsString
函数将类序列化为JSON时,我发现输出中存在重复的值
public class Movie {
private String movieName;
@JsonTypeInfo(use=Id.NAME,include=As.EXTERNAL_PROPERTY,property="movieName")
@JsonSubTypes({@JsonSubTypes.Type(value = StarWarsParams.class, name = "starwars")})
private MovieParams movieParams;
/* Getters and setters follow */
}
/* Empty class */
public class MovieParams {
}
public class StarWarsParams extends MovieParams{
private String characterName;
@JsonTypeInfo(use=Id.NAME,include=As.EXTERNAL_PROPERTY,property="characterName")
@JsonSubTypes({@JsonSubTypes.Type(value = SithParameters.class, name = "Darth Vader")})
private CharacterParams characterParams;
/* Getters and setters follow */
}
/* Empty class */
public class CharacterParams {
}
public class SithParameters extends CharacterParams {
private boolean canShootLightning;
}
执行转换的代码段如下所示:
Movie movie = new Movie();
movie.setMovieName("starwars");
StarWarsParams starWarsParams = new StarWarsParams();
starWarsParams.setCharacterName("Darth Vader");
SithParameters sithParameters = new SithParameters();
sithParameters.setCanShootLightning(false);
starWarsParams.setCharacterParams(sithParameters);
movie.setMovieParams(starWarsParams);
ObjectMapper mapper = new ObjectMapper();
String jsonStringSample = mapper.writeValueAsString(movie);
System.out.println(jsonStringSample);
{"movieName":"starwars","movieParams":{"characterName":"Darth Vader","characterParams":{"canShootLightning":false},"characterName":"Darth Vader"},"movieName":"starwars"}
movieName
和characterName
具有重复项的输出如下:
Movie movie = new Movie();
movie.setMovieName("starwars");
StarWarsParams starWarsParams = new StarWarsParams();
starWarsParams.setCharacterName("Darth Vader");
SithParameters sithParameters = new SithParameters();
sithParameters.setCanShootLightning(false);
starWarsParams.setCharacterParams(sithParameters);
movie.setMovieParams(starWarsParams);
ObjectMapper mapper = new ObjectMapper();
String jsonStringSample = mapper.writeValueAsString(movie);
System.out.println(jsonStringSample);
{"movieName":"starwars","movieParams":{"characterName":"Darth Vader","characterParams":{"canShootLightning":false},"characterName":"Darth Vader"},"movieName":"starwars"}
此问题出现在旧版本的Jackson上,例如1.9.2,而不是
com.fasterxml
中的最新版本。Jackson识别了两个字段,一个来自@JsonTypeInfo
注释,另一个来自getter。两种解决方案:
com.fasterxml
@JsonTypeInfo
注释移动到getter上,而不是字段上,例如
@JsonTypeInfo(use = Id.NAME, include = As.EXTERNAL_PROPERTY, property = "characterName")
public String getCharacterName() {
return characterName;
}
使用序列化定制的
JSON
对象非常简单。
我在我的项目中编写了一个类,以获得序列化的
JSONObject
。我正在给你一个想法如何在项目中实现这一点
应用程序(POJO类)
现在是ApplicationSerializer类,该类包含使用序列化逻辑进行的自定义
包org.webservice.business.serializer;
导入java.io.IOException;
导入org.webservice.business.dto.Application;
导入com.fasterxml.jackson.core.JsonGenerator;
导入com.fasterxml.jackson.core.JsonProcessingException;
导入com.fasterxml.jackson.databind.JsonSerializer;
导入com.fasterxml.jackson.databind.SerializerProvider;
公共类应用程序序列化程序扩展了JsonSerializer{
@凌驾
public void serialize(应用程序prm_objObjectToSerialize、JsonGenerator prm_objJsonGenerator、SerializerProvider prm_objSerializerProvider)引发IOException、JsonProcessingException{
if(null==prm_对象作业对象序列化){
}否则{
试一试{
prm_objjsonggenerator.writeStartObject();
prm_objjsonggenerator.writeNumberField(“amount”,prm_objObjectToSerialize.getAmount());
prm_objjsonggenerator.writeNumberField(“duration”,prm_objObjectToSerialize.getDuration());
prm_objjsonggenerator.writeStringField(“businesstype”,prm_objObjectToSerialize.getBusinessType());
prm_objjsonggenerator.writeStringField(“currency”,prm_objObjectToSerialize.getCurrency());
}捕获(异常v_异常){
v_exception.printStackTrace()
}最后{
prm_objjsonggenerator.writeEndObject();
}
}
}
你确定,你没有做任何其他事情,因为我刚刚用Jackson 2.7.2尝试了你的示例,它输出了正确的JSON。谢谢@Manos。在我将@JsonTypeInfo
注释移到getter上后,问题得到了解决。顺便说一句,我使用的是Jackson 2.2.3版,我试图给出writeValueAsString
到readValue
将JSON转换回类。但是我得到了无法识别的字段“characterName”
错误。我也尝试了2.7.0 Jackson版本,但结果仍然是一样的。知道原因吗?对于最新版本的Jackson,你可以在字段上添加@JsonTypeInfo
。或者在setter和getterThank上添加它。在字段上添加@JsonTypeInfo
解决了这个问题。但是看起来我必须使用其他库,因为我的一个用例不受Jackson支持。问题描述位于以下链接:谢谢。现在使用@Manos answer。我可能也会尝试一下。