Spring Boot调用POST接口获取数据时遭遇500错误求助
问题排查与修复方案
看起来你的Spring Boot代码调用Druid API时出现500错误,核心问题出在请求体格式不匹配和一些代码细节错误上,我帮你一步步分析并修正:
核心问题分析
请求体类型错误
你使用了MultiValueMap作为请求体,但这个类是用来处理application/x-www-form-urlencoded格式的表单数据的。虽然你设置了ContentType为APPLICATION_JSON,RestTemplate并不会把MultiValueMap自动序列化为Druid需要的JSON对象,反而会生成类似queryType=scan&dataSource=EmpActive的表单格式,导致Druid无法解析请求体,返回500错误。变量名笔误
代码中new HttpEntity<>(body, headers)里的body是未定义的变量,应该是你之前创建的bodyMap,这会导致编译错误(如果运行时没报错可能是你实际代码里的笔误)。响应类型不匹配
你用JSONPObject接收响应,但Druid返回的是标准JSON数组,不是JSONP格式,这会导致反序列化失败。
修复后的代码示例
第一步:创建请求体POJO类
先定义一个和Druid要求的请求体结构匹配的类,让RestTemplate能正确序列化为JSON:
import lombok.Data; // 可以用Lombok简化代码,也可以手动写getter/setter @Data public class DruidScanQuery { private String queryType; private String dataSource; private String intervals; // 构造函数 public DruidScanQuery(String queryType, String dataSource, String intervals) { this.queryType = queryType; this.dataSource = dataSource; this.intervals = intervals; } }
第二步:修改调用逻辑
替换MultiValueMap为自定义POJO,修正变量名并调整响应接收类型:
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.client.RestTemplate; import java.util.List; import java.util.Map; public String respond() { String uri = "http://10.68.192.208:8082/druid/v2/"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); // 用自定义POJO构建符合要求的JSON请求体 DruidScanQuery query = new DruidScanQuery( "scan", "EmpActive", "2008-03-18T12:04:00.000Z/2009-10-23T14:39:00.000Z" ); HttpEntity<DruidScanQuery> request = new HttpEntity<>(query, headers); RestTemplate restTemplate = new RestTemplate(); // 用List<Map<String, Object>>接收Druid返回的JSON数组,也可以自定义响应POJO类 List<Map<String, Object>> response = restTemplate.postForObject(uri, request, List.class); // 将响应转为字符串返回 ObjectMapper mapper = new ObjectMapper(); try { return mapper.writeValueAsString(response); } catch (JsonProcessingException e) { e.printStackTrace(); return "Failed to parse response"; } }
额外调试建议
如果想确认发送的请求体是否和Postman一致,可以给RestTemplate添加拦截器打印请求内容:
restTemplate.getInterceptors().add((request, body, execution) -> { System.out.println("实际发送的请求体: " + new String((byte[]) body, java.nio.charset.StandardCharsets.UTF_8)); return execution.execute(request, body); });
内容的提问来源于stack exchange,提问作者Suroor Ahmmad
相关产品推荐
相关产品推荐

