Spring Boot POST接口返回400错误排查求助
问题排查:Spring Boot POST接口返回400 Bad Request
开发的Spring Boot POST接口findByCriteria持续返回400错误,但health和test接口可正常调用,以下是相关代码与请求信息,及对应的排查解决方案:
相关代码与请求信息
1. Payload实体类(CriteriaVO)
public class CriteriaVO implements Serializable { private static final long serialVersionUID = -4809182119185775529L; private final List<String> categories; private final List<String> subCategories; public CriteriaVO(List<String> categories, List<String> subCategories) { super(); this.categories = categories; this.subCategories = subCategories; } public List<String> getCategories() { return categories; } public List<String> getSubCategories() { return subCategories; } }
2. RestController类(QuestionsController)
@RestController @RequestMapping("questions") public class QuestionsController { @Autowired private QuestionDao questionDaoImpl; @GetMapping(path= "health", produces = MediaType.APPLICATION_JSON_VALUE) public String health() { return "Wish all good health!"; } @PostMapping(path = "findByCriteria", produces = MediaType.APPLICATION_JSON_VALUE, consumes=MediaType.APPLICATION_JSON_VALUE, name = "findByCriteria") public List<Question> findByCriteria(@RequestBody CriteriaVO criteria) { System.out.println("test"); List<Question> questions = this.questionDaoImpl.findByCriteria(criteria.getCategories(), criteria.getSubCategories()); return questions; } @PostMapping(path = "test", produces = MediaType.TEXT_PLAIN_VALUE, consumes=MediaType.TEXT_PLAIN_VALUE, name = "test") public String test(@RequestBody String test) { System.out.println(test); return "returned " + test; } }
3. 请求JSON参数
{"categories":["Observability"],"subCategories":["Tracing","General"]}
4. Postman生成的curl命令
curl --location 'localhost:8080/questions/findByCriteria' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data ' {"categories":["Observability"],"subCategories":["Tracing","General"]}'
排查步骤与解决方案
核心原因
400错误本质是请求JSON无法被Jackson正确反序列化为CriteriaVO实例:
CriteriaVO仅提供带参构造器,且字段为final,Jackson默认无足够能力实例化并赋值该类对象。
具体修复方案
方案1:手动添加无参构造器
Jackson需要无参构造器来初始化对象,即使字段是final,Spring Boot默认的Jackson配置支持通过反射为final字段赋值:
public class CriteriaVO implements Serializable { private static final long serialVersionUID = -4809182119185775529L; private final List<String> categories; private final List<String> subCategories; // 添加无参构造器 public CriteriaVO() { this.categories = new ArrayList<>(); this.subCategories = new ArrayList<>(); } public CriteriaVO(List<String> categories, List<String> subCategories) { super(); this.categories = categories; this.subCategories = subCategories; } public List<String> getCategories() { return categories; } public List<String> getSubCategories() { return subCategories; } }
方案2:用Lombok简化代码(推荐)
引入Lombok依赖后,通过注解自动生成构造器与Getter方法,避免手动编写重复代码:
import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.List; @Getter @NoArgsConstructor @AllArgsConstructor public class CriteriaVO implements Serializable { private static final long serialVersionUID = -4809182119185775529L; private List<String> categories; private List<String> subCategories; }
额外排查优化点
- 修正curl命令的请求体格式:原命令中
--data后有多余换行,虽然Jackson通常忽略,但建议移除换行保证JSON格式严谨:curl --location 'localhost:8080/questions/findByCriteria' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --data '{"categories":["Observability"],"subCategories":["Tracing","General"]}' - 查看Spring Boot日志:开启
DEBUG级别日志,可获取Jackson反序列化失败的具体细节,帮助快速定位问题。
内容的提问来源于stack exchange,提问作者AbNig
相关产品推荐
相关产品推荐

