JsonMappingException:无法从START_OBJECT标记中反序列化枚举实例

时间:2017-01-04 19:10:42

标签: spring-mvc enums jackson set

我的Json看起来像是

{
name: "math",
code:null,
description:"Mathematics",
id:null,
name:"math",
noExam:null,
teacher:{
	id: "57869ced78aa7da0d2ed2d92", 
	courseGroup:"LKG",
	experties:[{type: "SOCIALSTUDIES", id: "3"}, {type: "PHYSICS", id: "4"}]

	},
id:"57869ced78aa7da0d2ed2d92"
}

如果你看到我的实体类,我在Teacher.java中有一组枚举

当我尝试发布时,我收到错误

JsonMappingException: Can not deserialize instance of com.iris.fruits.domain.enumeration.Experties out of START_OBJECT token

我已尝试过几乎所有解决方案,例如DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY,但没有成功。

public class Subject implements Serializable {
// all the other fields 
    @JoinColumn(name = "teacher_id")
    private Teacher teacher;
  
  // getter and setter
  }



public class Teacher implements Serializable {
// all the other fields 
  
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private String id;

    @Enumerated(EnumType.STRING)
    @Column(name = "experties")
    @JsonProperty("experties")
    private List< Experties> experties;

  // getter and setter
  }


 
 @JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Experties implements Serializable {
    MATH(1,"MATH"),
    SCIENCE(2,"SCIENCE"),
    SOCIALSTUDIES(3,"SOCIALSTUDIES"),
    PHYSICS(4,"PHYSICS"), 
    CHEMISTRY(5,"CHEMISTRY");
	
	@JsonSerialize(using = ToStringSerializer.class) 
	private String type;
	
	@JsonSerialize(using = ToStringSerializer.class) 
	private Integer id;
	
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	
	
	Experties(Integer id, final String type) {
		this.id = id;		
		this.type = type; 
	}
	
	
}

3 个答案:

答案 0 :(得分:2)

您遇到此问题是因为enum@JsonFormat(shape = JsonFormat.Shape.OBJECT))中有一个自定义序列化程序。因此,要解决此问题,您需要一个自定义解串器。

您可以使用定义自定义解串器:

@JsonFormat(shape = JsonFormat.Shape.OBJECT) // custom serializer
@JsonDeserialize(using = MyEnumDeserializer.class) // custom deserializer
public enum Experties implements Serializable {
    ...
}

自定义解串器为:

public static class MyEnumDeserializer extends JsonDeserializer<Experties> {
    @Override
    public Experties deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        String type = node.get("type").asText();
        return Stream.of(Experties.values())
           .filter(enumValue -> enumValue.getType().equals(type))
           .findFirst()
           .orElseThrow(() -> new IllegalArgumentException("type "+type+" is not recognized"));
    }
}

当然,您可以使用其他反序列化器实现(例如,使用id字段代替type字段,检查idtype字段之间的一致性)

答案 1 :(得分:0)

你的类应该与json的结构相匹配。在你的输入中,json不应重复键。

我猜你上课了,应该如下:

public class Subject implements Serializable {
// all the other fields 
    String name;
    String code;
    String description;
    String id;
    String noExam;
    @JoinColumn(name = "teacher_id")
    private Teacher teacher;

  // getter and setter
  }



public class Teacher implements Serializable {
// all the other fields 

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private String id;

    @Enumerated(EnumType.STRING)
    @Column(name = "experties")
    @JsonProperty("experties")
    private List< Experties> experties;

    String courseGroup;
  // getter and setter
  }



 @JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Experties implements Serializable {
    MATH(1,"MATH"),
    SCIENCE(2,"SCIENCE"),
    SOCIALSTUDIES(3,"SOCIALSTUDIES"),
    PHYSICS(4,"PHYSICS"), 
    CHEMISTRY(5,"CHEMISTRY");

    @JsonSerialize(using = ToStringSerializer.class) 
    private String type;

    @JsonSerialize(using = ToStringSerializer.class) 
    private Integer id;

    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }


    Experties(Integer id, final String type) {
        this.id = id;       
        this.type = type; 
    }


}

答案 2 :(得分:0)

JsonDeserialize 注释添加到“教师”类的经验设置器中:

@JsonDeserialize(using = EnumDeserializer.class)
public void setExperties(List experties){
//...
}