Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ObjectMapper.writeValueAsString的输出中存在重复值_Java_Json_Serialization_Jackson_Polymorphism - Fatal编程技术网

Java ObjectMapper.writeValueAsString的输出中存在重复值

Java 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")

我正在使用Jackson
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。我可能也会尝试一下。