我正在使用Jackson ObjectMapper
来(de)序列化具有多态嵌套类的类。将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
和characterName
重复的输出如下:
{"movieName":"starwars","movieParams":{"characterName":"Darth Vader","characterParams":{"canShootLightning":false},"characterName":"Darth Vader"},"movieName":"starwars"}
答案 0 :(得分:1)
旧版本的Jackson会出现此问题,例如1.9.2但不是来自com.fasterxml
的最新内容。杰克逊从@JsonTypeInfo
注释中识别出两个字段,从getter中识别出一个字段。两种解决方案:
com.fasterxml
将@JsonTypeInfo
注释移到getter而不是字段上,例如
@JsonTypeInfo(use = Id.NAME, include = As.EXTERNAL_PROPERTY, property = "characterName")
public String getCharacterName() {
return characterName;
}
答案 1 :(得分:0)
使用序列化的自定义JSON
对象非常简单。
我在项目中写了一个类来获取序列化JSONObject
。我正在给你一个想法如何在项目中实现这一点。
申请(POJO班级)
import java.io.Serializable;
import java.util.List;
import org.webservice.business.serializer.ApplicationSerializer;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@JsonSerialize(using=ApplicationSerializer.class)
public class Application implements Serializable {
private static final long serialVersionUID = 1L;
private double amount;
private String businessType;
private String currency;
private int duration;
}
现在包含使用序列化逻辑的自定义的ApplicationSerializer类................
package org.webservice.business.serializer;
import java.io.IOException;
import org.webservice.business.dto.Application;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
public class ApplicationSerializer extends JsonSerializer<Application> {
@Override
public void serialize(Application prm_objObjectToSerialize, JsonGenerator prm_objJsonGenerator, SerializerProvider prm_objSerializerProvider) throws IOException, JsonProcessingException {
if (null == prm_objObjectToSerialize) {
} else {
try {
prm_objJsonGenerator.writeStartObject();
prm_objJsonGenerator.writeNumberField("amount", prm_objObjectToSerialize.getAmount());
prm_objJsonGenerator.writeNumberField("duration", prm_objObjectToSerialize.getDuration());
prm_objJsonGenerator.writeStringField("businesstype", prm_objObjectToSerialize.getBusinessType());
prm_objJsonGenerator.writeStringField("currency", prm_objObjectToSerialize.getCurrency());
} catch (Exception v_exException) {
v_exException.printStackTrace()
} finally {
prm_objJsonGenerator.writeEndObject();
}
}
}