Java Spring Boot请求体locker_id映射到UserLockRequest为空如何解决
根本问题梳理
- 字段映射不匹配:请求体中传输的是
locker_id,而UserLockRequest中定义的字段名为locker,Jackson默认按字段名精确匹配,二者无法对应。 - 类型不匹配:请求中传输的
locker_id是数值类型,而UserLockRequest中对应字段是自定义Locker类型,Jackson无法直接将数值转换为Locker实体对象。 - 校验注解使用错误:
@NotBlank仅适用于字符串类型的非空校验,作用在自定义对象上不会生效,对象非空校验应该使用@NotNull。
解决方案
第一步:修改UserLockRequest参数接收类
调整字段类型和映射规则,直接接收locker_id的值:
public class UserLockRequest { @NotNull @JsonProperty("locker_id") // 显式指定和JSON中locker_id字段的映射关系 private Long lockerId; public Long getLockerId() { return lockerId; } public void setLockerId(Long lockerId) { this.lockerId = lockerId; } }
如果项目全局都使用「JSON下划线命名、Java驼峰命名」的规则,也可以在配置文件中开启全局下划线转驼峰配置,不需要每个字段加@JsonProperty:
# application.yml配置 spring: jackson: property-naming-strategy: SNAKE_CASE
第二步:修改业务逻辑层代码
需要先根据接收到的lockerId查询对应的Locker实体,再赋值给User对象:
// 先注入Locker对应的持久层接口 @Autowired private LockerRepository lockerRepository; public Optional<User> lockUser(Long userId, UserLockRequest userLockRequest) { // 先判断用户是否存在,避免空指针异常 Optional<User> userOpt = userRepository.findById(userId); if (userOpt.isEmpty()) { return Optional.empty(); } // 查询对应的Locker实体 Optional<Locker> lockerOpt = lockerRepository.findById(userLockRequest.getLockerId()); if (lockerOpt.isEmpty()) { // 可根据业务需求抛出参数异常或返回空 return Optional.empty(); } User user = userOpt.get(); user.setLocker(lockerOpt.get()); userRepository.save(user); return Optional.of(user); }
注意事项
不要直接调用Optional.get(),如果查询结果为空会抛出NoSuchElementException,需要先判空再操作。如果确实需要UserLockRequest直接接收Locker类型,可以自定义Jackson反序列化器将ID转换为Locker实体,不过复杂度更高,不推荐常规场景使用。
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

