Java Jackson调用setter,但嵌套对象的字段仍为空
有一个类,其中包含另一个静态类。Jackson在反序列化json时调用setter。但是一些二传手并没有像预期的那样工作。Java Jackson调用setter,但嵌套对象的字段仍为空,java,json,jackson,Java,Json,Jackson,有一个类,其中包含另一个静态类。Jackson在反序列化json时调用setter。但是一些二传手并没有像预期的那样工作。 类别定义: @Entity @JsonIgnoreProperties(ignoreUnknown=true) @JsonPropertyOrder({ "name", "imageLink", "weeklyGross", "weeklyChange" }) public class WeeklyBoxOffice { @Embeddable public static
类别定义:
@Entity
@JsonIgnoreProperties(ignoreUnknown=true)
@JsonPropertyOrder({ "name", "imageLink", "weeklyGross", "weeklyChange" })
public class WeeklyBoxOffice {
@Embeddable
public static class WeeklyBoxOfficeID implements Serializable {
public String country;
public String name;
public WeeklyBoxOfficeID() {
}
}
public WeeklyBoxOffice() {
this.id = new WeeklyBoxOfficeID();
}
@EmbeddedId
@JsonUnwrapped
WeeklyBoxOfficeID id;
private long weeklyGross;
private double weeklyChange;
// "weeklyGross":"$294,710"
public void setWeeklyGross(String weeklyGross) throws ParseException {
System.out.println("setWeeklyGross called, weeklyGross = " + weeklyGross);
this.weeklyGross = (long) NumberFormat.getCurrencyInstance(Locale.US)
.parse(weeklyGross);
}
// "weeklyChange": "-57.1%"
public void setWeeklyChange(String weeklyChange) {
this.weeklyChange = weeklyChange.equals("-") ? 0 : Double.parseDouble(weeklyChange.replace('%', ' '));
}
public void setCountry(String country) {
this.id.country = country;
}
// @JsonProperty("name")
public void setName(String name) {
System.out.println("Set name caled, name = " + name);
this.id.name = name;
}
public void setMovie(Movie movie) {
this.movie = movie;
}
public static void main(String[] args) throws IOException {
String json = "{\n" +
" \"TrendingMovies\": [\n" +
" {\n" +
" \"name\": \"The Dark Tower\",\n" +
" \"weeklyGross\": \"$461,377\",\n" +
" \"weeklyChange\": \"5.0\"\n" +
" }\n" +
" ]\n" +
"}\n";
ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
List<WeeklyBoxOffice> list = mapper.readValue(mapper.readTree(json).get("TrendingMovies").toString(), new TypeReference<List<WeeklyBoxOffice>>() {});
list.forEach(System.out::println);
}
@实体
@JsonIgnoreProperties(ignoreUnknown=true)
@JsonPropertyOrder({“名称”、“图像链接”、“weeklyGross”、“weeklyChange”})
公共课周刊办公室{
@可嵌入
公共静态类WeeklyBoxOfficeID实现可序列化{
公共字符串国家;
公共字符串名称;
公共周刊BoxOfficeId(){
}
}
公共周刊牛津办公室(){
this.id=新的WeeklyBoxOfficeID();
}
@嵌入ID
@JsonUnwrapped
WeeklyBoxOfficeID;
私人长周刊;
私人双周刊;
//“weeklyGross”:“294710美元”
public void setWeeklyGross(字符串weeklyGross)引发ParseException{
System.out.println(“调用setWeeklyGross,weeklyGross=“+weeklyGross”);
this.weeklyGross=(长)NumberFormat.getCurrencyInstance(Locale.US)
.parse(weeklyGross);
}
//“每周变化”:“-57.1%”
public void setWeeklyChange(字符串weeklyChange){
this.weeklyChange=weeklyChange.equals(“-”)?0:Double.parseDouble(weeklyChange.replace('%,'');
}
公共国家/地区(字符串国家/地区){
this.id.country=国家;
}
//@JsonProperty(“名称”)
公共void集合名(字符串名){
System.out.println(“设置名称刻度,name=“+name”);
this.id.name=名称;
}
公共电影(电影){
这部电影=电影;
}
公共静态void main(字符串[]args)引发IOException{
字符串json=“{\n”+
“\'TrendingMovies\”:[\n”+
“{\n”+
“\'name\:\'The Dark Tower\”,\n”+
“\“weeklyGross\”:\“$461377\”,\n”+
“\“weeklyChange\”:\“5.0\”\n”+
“}\n”+
“]\n”+
“}\n”;
ObjectMapper mapper=new ObjectMapper().enable(SerializationFeature.INDENT_输出);
List List=mapper.readValue(mapper.readTree(json).get(“TrendingMovies”).toString(),new TypeReference(){});
list.forEach(System.out::println);
}
输出:
设置名称caled,名称=黑暗塔
setWeeklyGross呼叫,weeklyGross=$461377
WeeklyBoxOffice{id=WeeklyBoxOffice id{country='null',name='null'},
weeklyGross=461377,weeklyChange=5.0}
为什么调用
setName
没有效果,而setWeeklyGross
和setWeeklyChange
没有效果,嵌套对象的字段仍然为空?问题是@JsonUnwrapped
如果您删除它,它将正常工作。如果您使用调试器跟踪代码,您将看到Jackson(按此顺序):
WeeklyBoxOffice
构造函数,该构造函数将WeeklyBoxOfficeID
设置为空对象(全部为null)setName
,并在WeeklyBoxOfficeID
中设置名称name
字段,因为它以前被getName
使用。因此,它现在将其设置为null如果您保留
@JsonUnwrapped
,但删除setCountry
和setName
设置器,则代码也会工作,这可能更简单。基本上使用一个或另一个设置器。问题在于@JsonUnwrapped
,如果您删除它,代码会工作正常。如果您使用调试器跟踪代码,您会看到这一点杰克逊(按此顺序):
WeeklyBoxOffice
构造函数,该构造函数将WeeklyBoxOfficeID
设置为空对象(全部为null)setName
,并在WeeklyBoxOfficeID
中设置名称name
字段,因为它以前被getName
使用。因此,它现在将其设置为null@JsonUnwrapped
,但删除setCountry
和setName
设置器,则代码也可以工作,这两个设置器可能更简单。基本上可以使用其中一个