17370845950

Java RestTemplate JSON反序列化字段为空的解决方案

使用resttemplate将json数组映射为java对象数组时,若实体类字段始终为null,通常因json键名与java字段名不匹配且缺少反序列化注解导致;添加@jsonproperty显式绑定字段可解决此问题。

当RestTemplate返回Employee[]却所有字段均为null,根本原因在于Jackson默认无法自动将JSON中的下划线命名(如employeeId)或嵌套结构(如email数组中的HTML链接)映射到Java驼峰字段,尤其在字段名不完全一致、存在嵌套或特殊格式时,反序列化会静默失败。

你的JSON中email是一个字符串数组(含HTML 标签),而Employee类中定义的是单个String email字段——这本身就会导致反序列化失败。此外,employeeId在JSON中是字符串("123"),但Java字段为Long类型,也需兼容处理。

✅ 正确做法如下:

  1. 为每个字段添加 @JsonProperty 注解,明确指定JSON字段名:
    import com.fasterxml.jackson.annotation.JsonProperty;

public class Employee { @JsonProperty("employeeId") private Long employeeId;

@JsonProperty("firstName")
private String firstName;

@JsonProperty("lastName")
private String lastName;

@JsonProperty("position")
private String position;

@JsonProperty("email")
private List email; // 注意:JSON中是数组,应声明为List

// 构造函数、getter/setter(必须提供!)
public Employee() {}

// getter/setter 略(IDE可自动生成)

}

2. **调整数据访问逻辑**(避免空指针):  
```java
ResponseEntity response = restTemplate.exchange(
    builder.build().encode().toUri(),
    HttpMethod.GET,
    requestEntity,
    Employee[].class
);

if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
    for (Employee emp : response.getBody()) {
        System.out.println("ID: " + emp.getEmployeeId());
        System.out.println("Name: " + emp.getFirstName() + " " + emp.getLastName());
        System.out.println("Email (first): " + 
            (emp.getEmail() != null && !emp.getEmail().isEmpty() ? 
                emp.getEmail().get(0) : "N/A"));
    }
}

⚠️ 重要注意事项:

  • @JsonProperty 是Jackson核心注解,确保项目已引入 jackson-databind(Spring Boot 默认包含);
  • 若需从HTML邮箱链接中提取纯邮箱地址(如 [email protected] → [email protected]),需额外使用JSoup或正则解析,不能依赖Jackson自动完成
  • employeeId 字段若JSON中为字符串(如 "123"),建议改为 String employeeId 或添加 @JsonDeserialize(using = StringToLongDeserializer.class) 自定义转换器;
  • 始终检查 response.getBody() 是否为 null,并验证HTTP状态码,避免NPE。

? 进阶建议:对复杂嵌套响应(如外层data对象),可定义顶层封装类(如ApiResponse),而非直接映射数组,提升健壮性与可维护性。