如何使用Spring RestTemplate发送JSON格式POST数据?指定数据POST能否实现?
嘿,这个问题我太熟了,来给你一步步拆解清楚~
首先,RestTemplate本身就支持发送JSON格式的POST请求,核心是要确保它配置了合适的消息转换器(比如MappingJackson2HttpMessageConverter,用来处理JSON的序列化和反序列化)。
步骤1:配置RestTemplate
如果是Spring Boot项目,通常可以直接注入RestTemplate,但如果需要自定义配置,你可以这样创建Bean:
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); // 添加Jackson消息转换器,确保能处理JSON MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON)); restTemplate.getMessageConverters().add(converter); return restTemplate; } }
步骤2:发送JSON POST请求
有几种常用的方式,我给你举两个最实用的例子:
方式1:使用postForObject(直接获取响应结果)
假设你要发送的JSON数据对应一个实体类UserRequest:
// 定义请求实体类,字段会自动序列化为JSON键 public class UserRequest { private String username; private String email; // 构造器、getter、setter省略 }
然后在业务代码里发送请求:
@Autowired private RestTemplate restTemplate; public void sendJsonPost() { String url = "https://your-api-endpoint.com/users"; UserRequest requestBody = new UserRequest("john_doe", "john@example.com"); // 发送POST请求,自动将实体类转为JSON,同时接收响应(这里假设响应是String类型) String response = restTemplate.postForObject(url, requestBody, String.class); System.out.println("响应结果:" + response); }
方式2:使用exchange(更灵活,支持自定义请求头、响应类型等)
如果需要设置自定义请求头(比如Authorization),用exchange更合适:
public void sendJsonPostWithHeaders() { String url = "https://your-api-endpoint.com/users"; UserRequest requestBody = new UserRequest("jane_smith", "jane@example.com"); // 设置请求头 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.set("Authorization", "Bearer your-token-here"); // 封装请求体和头 HttpEntity<UserRequest> requestEntity = new HttpEntity<>(requestBody, headers); // 发送请求,指定响应类型为UserResponse(假设你有对应的响应实体类) ResponseEntity<UserResponse> responseEntity = restTemplate.exchange( url, HttpMethod.POST, requestEntity, UserResponse.class ); System.out.println("响应状态码:" + responseEntity.getStatusCode()); System.out.println("响应体:" + responseEntity.getBody()); }
具体怎么实现,要看你说的「特定格式」是哪种场景,我给你列几种常见情况:
场景1:自定义JSON结构(比如字段命名、日期格式等)
如果需要让序列化后的JSON符合特定规则(比如下划线命名、自定义日期格式),你可以自定义ObjectMapper并配置到消息转换器里:
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); // 自定义ObjectMapper ObjectMapper objectMapper = new ObjectMapper(); // 设置字段命名策略为下划线(比如username -> user_name) objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE); // 设置日期格式 objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); // 忽略null字段 objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper); converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON)); restTemplate.getMessageConverters().add(converter); return restTemplate; } }
这样你的实体类序列化后就会自动按照这个规则生成JSON了。
场景2:动态JSON结构(不需要实体类)
如果你的请求格式是动态的,不想定义实体类,可以直接用HashMap或者JSONObject(比如org.json.JSONObject)作为请求体:
public void sendDynamicJsonPost() { String url = "https://your-api-endpoint.com/data"; HashMap<String, Object> requestBody = new HashMap<>(); requestBody.put("name", "Alice"); requestBody.put("age", 30); requestBody.put("hobbies", Arrays.asList("reading", "hiking")); String response = restTemplate.postForObject(url, requestBody, String.class); System.out.println("响应:" + response); }
场景3:非JSON的特定格式(比如自定义文本格式)
如果你的特定格式不是JSON(比如XML、CSV或者自定义的字符串格式),那你可以自定义HttpMessageConverter来处理序列化逻辑,然后添加到RestTemplate的转换器列表里。比如要发送CSV格式,你可以实现HttpMessageConverter<YourDataClass>,重写write方法把数据转为CSV字符串,然后配置到RestTemplate中。
总之,RestTemplate的扩展性很强,几乎能满足所有自定义格式的发送需求~
内容的提问来源于stack exchange,提问作者Atang Sutisna

