Spring Boot应用POST请求读取失败(400错误)求助
Spring Boot POST端点400错误排查与解决
问题描述
编写了一个简单的CRUD Spring Boot应用,但POST端点/api/v1/users/4/animals无法正常工作。发送的请求体如下:
{ "nickname": "bob", "kind": "cat", "birthday": "12.02.2020", "vetRecords": null }
每次收到400错误响应:
{ "type": "about:blank", "title": "Bad Request", "status": 400, "detail": "Failed to read request", "instance": "/api/v1/users/4/animals" }
调试断点未触发,CommonsRequestLoggingFilter日志显示请求payload正确,但请求无法被读取。
相关代码
Controller
@PostMapping("{id}/animals") public AnimalDto createAnimal(@PathVariable Long id, @Validated(OnCreate.class) @RequestBody AnimalDto animalDto) { Animal animal = animalMapper.toEntity(animalDto); Animal createdAnimal = animalService.create(animal, id); return animalMapper.toDto(createdAnimal); }
DTO
@Data @NoArgsConstructor @AllArgsConstructor public class AnimalDto { @NotNull(message = "Id must be not null", groups = OnUpdate.class) private Long id; @NotNull(message = "Animal name must not be null", groups = {OnUpdate.class, OnCreate.class}) @Length(max = 256, message = "Animal name must be less than 256 symbols") private String nickname; @NotNull(message = "Animal kind must not be null", groups = {OnUpdate.class, OnCreate.class}) @Length(max = 256, message = "Animal kind must be less than 256 symbols") private String kind; @NotNull(message = "Animal age must not be null", groups = {OnUpdate.class, OnCreate.class}) private Date birthday; private List<VetRecord> vetRecords; }
Entity
@Data @AllArgsConstructor @NoArgsConstructor public class Animal { private Long id; private String nickname; private String kind; private Date birthday; private List<VetRecord> vetRecords; }
Mapper(MapStruct)
@Mapper(componentModel = "spring") public interface AnimalMapper { AnimalDto toDto(Animal animal); List<AnimalDto> toDto(List<Animal> animals); Animal toEntity(AnimalDto animalDto); }
排查与解决步骤
1. 日期格式解析错误(最可能原因)
DTO中birthday为java.util.Date类型,默认Jackson解析器无法识别12.02.2020这种dd.MM.yyyy格式的字符串,导致请求体解析失败。
解决方法:
- 给
birthday字段添加格式化注解:
@NotNull(message = "Animal age must not be null", groups = {OnUpdate.class, OnCreate.class}) @JsonFormat(pattern = "dd.MM.yyyy") private Date birthday;
- 或者全局配置Jackson日期格式,在
application.properties中添加:
spring.jackson.date-format=dd.MM.yyyy spring.jackson.time-zone=UTC # 根据业务需求设置时区
2. 检查请求Content-Type
确保请求头的Content-Type设置为application/json,如果是表单提交或其他类型,Jackson无法解析请求体,会直接返回400错误。
3. 验证VetRecord类的可序列化性
虽然请求中vetRecords为null,但如果VetRecord类不满足Jackson序列化要求,也会导致解析失败:
- 确保
VetRecord有无参构造函数 - 字段有对应的getter/setter(使用Lombok的
@Data注解可自动生成) - 无循环引用或无法解析的复杂类型
4. 开启详细日志定位问题
添加Jackson和Spring MVC的调试日志,查看具体解析异常:
在application.properties中配置:
logging.level.com.fasterxml.jackson=DEBUG logging.level.org.springframework.web.servlet.mvc.method.annotation=DEBUG
日志会输出解析过程中的具体错误信息,帮助精准定位问题。
5. 确认分组校验配置
虽然解析阶段失败会跳过校验,但需确认OnCreate和OnUpdate分组接口正确定义:
public interface OnCreate {} public interface OnUpdate {}
确保接口为public,且Controller的@Validated注解正确引用分组。
内容的提问来源于stack exchange,提问作者Jan Potarski
相关产品推荐
相关产品推荐

