ObjectMapper.writeValueAsString的输出中的重复值

时间:2016-03-09 10:44:00

标签: java json serialization jackson polymorphism

我正在使用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);

movieNamecharacterName重复的输出如下:

{"movieName":"starwars","movieParams":{"characterName":"Darth Vader","characterParams":{"canShootLightning":false},"characterName":"Darth Vader"},"movieName":"starwars"}

2 个答案:

答案 0 :(得分:1)

旧版本的Jackson会出现此问题,例如1.9.2但不是来自com.fasterxml的最新内容。杰克逊从@JsonTypeInfo注释中识别出两个字段,从getter中识别出一个字段。两种解决方案:

  1. com.fasterxml
  2. 使用更新版本的Jackson
  3. @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();
        }
    }
  }