jackson JSONMap异常错误:无法反序列化START_OBJECT标记之外的枚举示例

wz8daaqr  于 2022-11-09  发布在  其他
关注(0)|答案(4)|浏览(164)

我的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"
}

如果您看到我的实体类,我在www.example.com中有一组枚举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; 
	}

}
hmtdttj4

hmtdttj41#

出现此问题的原因是您的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字段之间的一致性)。

sshcrbum

sshcrbum2#

你的类应该与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; 
    }

}
6ljaweal

6ljaweal3#

JsonDeserialize注解添加到Teacher类中的 experties setter:

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

4smxwvx54#

您遇到这个问题是因为您在枚举@JsonFormat(shape = JsonFormat.Shape.OBJECT)中有一个自定义序列化程序。Jackson不知道如何将对象从json反序列化到枚举中。您可以创建“creator”方法来轻松解决这个问题:

public enum Experties implements Serializable {
    @JsonCreator
    public Experties(String type) {
        // here you can use "type" attribute from json object to create your Enum instance. If you need, you can also add as parameter "Integer Id", as it is in your enum json representation.
        return valueOf(type);
    }
}

相关问题