Jackson反序列化报错Cannot invoke JsonNode.numberValue()求助
问题原因排查
- 直接触发空指针的错误:你自定义反序列化器中使用
node.get(0)尝试按索引取节点值,但你接收的JSON根节点是对象类型不是数组,不存在索引为0的元素,该方法返回null,调用numberValue()就抛出NPE。 - 逻辑错误1:你的JSON中
group字段是转义后的JSON字符串,不是嵌套JSON对象,nomGroup、idGrp都不存在于根节点下,直接从根节点取这两个字段肯定拿不到值。 - 逻辑错误2:Group类的属性名是
NomGroup(首字母大写),但JSON内嵌的group字符串中字段是nomGroup(首字母小写),属性名不匹配会导致反序列化失败。 - 逻辑错误3:Employe类的全参构造方法没有对
group属性赋值,即使反序列化拿到Group对象也没法注入到Employe实例中。 - 测试代码错误:main方法中你new了空的Employe对象序列化后再反序列化,空对象的所有字段都是null,反序列化时调用
node.get("xxx").intValue()这类方法也会触发空指针,应该用你实际收到的JSON字符串做测试。
修复步骤
1. 修正Group类属性名匹配问题
给Group类的属性加@JsonProperty注解适配JSON字段名,或者直接修改属性名小写开头,同时补全getter/setter:
@Entity @Table(name="groups") public class Group implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long idGrp; @JsonProperty("nomGroup") private String NomGroup; public Group(){ } public Group(Long id, String nomGroup) { super(); this.idGrp = id; NomGroup = nomGroup; } // 补全所有属性的getter、setter方法 }
2. 修正Employe构造方法
给全参构造加group属性赋值逻辑:
public Employe(Integer matricule, String nom, String prenom, String nom_ar, String prenom_ar, int age, String description, String email, int codeP, int numTele, String adresse, String ville, Group group) { super(); this.matricule = matricule; this.nom = nom; this.prenom = prenom; this.nom_ar = nom_ar; this.prenom_ar = prenom_ar; this.age = age; this.description = description; this.email = email; this.codeP = codeP; this.numTele = numTele; this.adresse = adresse; this.ville = ville; this.group = group; // 补全这行赋值逻辑 }
3. 重写自定义反序列化器逻辑
先把group字段的JSON字符串解析成JsonNode,再取对应字段,同时使用asInt()/asText()替代强制类型转换避免空指针:
public class GroupDeserlialize extends StdDeserializer<Employe> { private static final ObjectMapper innerMapper = new ObjectMapper(); public GroupDeserlialize() { this(null); } public GroupDeserlialize(Class<?> vc) { super(vc); } @Override public Employe deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonNode node = p.getCodec().readTree(p); int matricule = node.get("matricule").asInt(); String nom = node.get("nom").asText(); String prenom = node.get("prenom").asText(); String nom_ar = node.get("nom_ar").asText(); String prenom_ar = node.get("prenom_ar").asText(); int age = node.get("age").asInt(); String description = node.get("description").asText(); String email = node.get("email").asText(); String adresse = node.get("adresse").asText(); String ville = node.get("ville").asText(); int codeP = node.get("codeP").asInt(); int numTele = node.get("numTele").asInt(); // 解析group内嵌的JSON字符串 String groupJsonStr = node.get("group").asText(); JsonNode groupNode = innerMapper.readTree(groupJsonStr); Long idGrp = groupNode.get("idGrp").asLong(); String nomGroup = groupNode.get("nomGroup").asText(); Group group = new Group(idGrp, nomGroup); return new Employe(matricule, nom, prenom, nom_ar, prenom_ar, age, description, email, codeP, numTele, adresse, ville, group); } }
4. 修正测试代码
用你实际的业务JSON字符串测试,不要用空对象序列化后的结果:
public static void main(String[] args) throws JsonProcessingException { SpringApplication.run(CniAppApplication.class, args); // 替换为你实际接收的JSON字符串 String jsonStr = "{\n" + " \"matricule\" : \"125\",\n" + " \"nom\" : \"Assaibi\",\n" + " \"prenom\" : \"Takwa\",\n" + " \"nom_ar\" : \"Assaibi\",\n" + " \"prenom_ar\" : \"Takwa\",\n" + " \"age\" : 34,\n" + " \"description\" : \"kjjhhdh\",\n" + " \"codeP\" : \"2087\",\n" + " \"email\" : \"takwaassaibi08@gmail.com\",\n" + " \"numTele\" : \"51890562\",\n" + " \"adresse\" : \"4270 citè folla agba Tunis\",\n" + " \"ville\" : \"Tunis\",\n" + " \"group\" : \"{\\n \\\"nomGroup\\\": \\\"groupeMembre\\\",\\n \\\"idGrp\\\": 3\\n}\"\n" + "}"; ObjectMapper mapper = new ObjectMapper(); Employe itemWithOwner = mapper.readValue(jsonStr, Employe.class); }
内容的提问来源于stack exchange,提问作者Takwa
相关产品推荐
相关产品推荐

