RestTemplate调用POST API遇HttpClientErrorException:400 null问题求助
排查RestTemplate POST请求400错误的解决方案
我来帮你一步步拆解这个HttpClientErrorException: 400 null的问题——这本质是服务端认为你的请求格式或内容不符合要求,咱们从几个核心点入手排查:
1. 最直接的问题:实体类缺少getter/setter方法
你的RouteDropPoint类只定义了dropPointList字段,但没有提供getter和setter方法。Spring默认的JSON消息转换器(比如Jackson)在序列化对象时,依赖getter读取字段值,反序列化时依赖setter赋值。没有这些方法的话,发送的请求体要么是空JSON{},要么根本无法正确序列化,直接导致服务端解析失败返回400。
解决方法:
给RouteDropPoint添加getter/setter,或者用Lombok的@Data注解自动生成:
// 方式1:手动添加getter/setter public class RouteDropPoint { private List<String> dropPointList; public List<String> getDropPointList() { return dropPointList; } public void setDropPointList(List<String> dropPointList) { this.dropPointList = dropPointList; } } // 方式2:用Lombok简化(需要引入Lombok依赖) import lombok.Data; @Data public class RouteDropPoint { private List<String> dropPointList; }
2. 确认服务端的请求格式预期
你一开始直接传List<String>失败,后来封装成RouteDropPoint还是失败,这需要明确服务端接口的接收规则:
- 如果服务端接口是用
@RequestBody List<String> dropPointList接收参数,那你最初的思路是对的,但直接传List给RestTemplate时,需要用ParameterizedTypeReference指定泛型类型,否则消息转换器无法正确识别:// 直接发送List<String>的正确写法 HttpEntity<List<String>> requestEntity = new HttpEntity<>(validDrops, headers); ResponseEntity<List<DropPointData>> responseEntity = restTemplate.exchange( uri, HttpMethod.POST, requestEntity, new ParameterizedTypeReference<List<DropPointData>>() {} ); - 如果服务端确实期望接收
RouteDropPoint封装对象,那解决完getter/setter问题后,请求格式就会正确,400错误应该会消失。
3. 验证发送的请求体是否正确
建议你在发送请求前,先打印实际要发送的JSON内容,确认格式是否符合服务端要求:
ObjectMapper mapper = new ObjectMapper(); try { RouteDropPoint rd = new RouteDropPoint(); rd.setDropPointList(validDrops); // 打印序列化后的JSON System.out.println("请求体内容:" + mapper.writeValueAsString(rd)); } catch (JsonProcessingException e) { e.printStackTrace(); }
如果打印结果是空对象{},说明还是getter/setter的问题;如果是{"dropPointList": ["xxx", "yyy"]}这种格式,就说明序列化正常,需要去排查服务端的接口定义。
4. 额外优化点(非直接错误原因)
你的代码每次调用方法都new一个RestTemplate,这不是最佳实践。建议把RestTemplate注册成Spring Bean,通过依赖注入使用,避免重复创建实例:
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } } // 在业务类中注入 @Autowired private RestTemplate restTemplate;
内容的提问来源于stack exchange,提问作者user3763375
相关产品推荐
相关产品推荐

