1.2. 定义业务REST API

下面我们为Person类定义简单的Rest api:

@PostMapping(value = "/createPerson", consumes = "application/json", produces = "application/json")
public Person createPerson(@RequestBody Person person) {
    return personService.saveUpdatePerson(person);
@PostMapping(value = "/updatePerson", consumes = "application/json", produces = "application/json")
public Person updatePerson(@RequestBody Person person, HttpServletResponse response) {
    response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentContextPath()
      .path("/findPerson/" + person.getId()).toUriString());
    return personService.saveUpdatePerson(person);

我们需要发送json格式post请求数据,为此,在两个方法的@PostMapping中增加consumes属性并设置值为“application/json”。类似的,设置produces属性值为“application/json”,为了告诉Spring我们希望响应数据也是json格式。

person参数前的注解@RequestBody,表明person对象和http请求体绑定。最后两个方法返回Person对象会绑定至http响应体。如果给api类增加@RestController注解,则所有api方法都带有@ResponseBody注解。

2. 使用RestTemplate

现在写几个单元测试,测试Person rest api。我们尝试使用RestTemplate发送post请求给Person api,共三个方法: postForObject, postForEntity, and postForLocation。

开始实现单元测试之前,先定义setup方法初始化单元测试方法中使用的对象:

@BeforeClass
public static void runBeforeAllTestMethods() {
    createPersonUrl = "http://localhost:8082/spring-rest/createPerson";
    updatePersonUrl = "http://localhost:8082/spring-rest/updatePerson";
    restTemplate = new RestTemplate();
    headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
   ObjectNode personJsonObject = objectMapper.createObjectNode();
   personJsonObject.put("id", 1);
   personJsonObject.put("name", "John");

除了setup方法,还要引入ObjectMapper对象转换JSON字符串为JSONNode对象:

private final ObjectMapper objectMapper = new ObjectMapper();

我们前面提到,post请求数据使用json格式。因此,在请求头中增加 Content-Type属性,值为APPLICATION_JSON 。Spring的 HttpHeaders提供不同的方法访问请求头信息。这里需要通过setContentType方法设置Content-Type 属性值为 application/json。然后给请求对象附加头信息。

2.1. 使用postForObject方法发送json

RestTemplate的postForObject 方法post对象给uri并返回新的对象。返回值自动被转换为responseType参数指定的类型,这里是字符串。

我们的需求是发送post请求至person api,创建新的Person对象并响应中包括新创建的对象。
首先,基于personJsonObject构建HttpEntity 类型的请求对象,并在请求头中指定Content-Type。然后调用postForObject 方法发送json请求体:

@Test
public void givenDataIsJson_whenDataIsPostedByPostForObject_thenResponseBodyIsNotNull()
  throws IOException {
    HttpEntity<String> request = new HttpEntity<String>(personJsonObject.toString(), headers);
    String personResultAsJsonStr = restTemplate.postForObject(createPersonUrl, request, String.class);
    JsonNode root = objectMapper.readTree(personResultAsJsonStr);
    assertNotNull(personResultAsJsonStr);
    assertNotNull(root);
    assertNotNull(root.path("name").asText());

该示例中 postForObject() 方法返回字符串响应体。我们也可以通过设置responseType参数使其返回Person类型:

Person person = restTemplate.postForObject(createPersonUrl, request, Person.class);
assertNotNull(person);
assertNotNull(person.getName());

实际上我们的请求处理方法(createPersonUrl 参数匹配的)产生json格式的响应体,但对postForObject 方法没有限制,通过设置responseType参数可以自动转换为响应的java类型。

2.2. 使用postForEntity发送json

相比于postForObject()方法, postForEntity() 返回响应体为 ResponseEntity 类型,其他两个方法功能一致。

我们的需求是发送post请求至person api,创建新的Person对象并返回ResponseEntity类型响应体。可以使用postForEntity实现该功能:

@Test
public void givenDataIsJson_whenDataIsPostedByPostForEntity_thenResponseBodyIsNotNull()
  throws IOException {
    HttpEntity<String> request = new HttpEntity<String>(personJsonObject.toString(), headers);
    ResponseEntity<String> responseEntityStr = restTemplate.
      postForEntity(createPersonUrl, request, String.class);
    JsonNode root = objectMapper.readTree(responseEntityStr.getBody());
    assertNotNull(responseEntityStr.getBody());
    assertNotNull(root.path("name").asText());

类似的,也可以设置responseType 参数转换响应体为Java类型。这里我们能够返回响应体为ResponseEntity,也能返回响应为 ResponseEntity 对象,只要设置responseType参数为 Person.class:

ResponseEntity<Person> responseEntityPerson = restTemplate.
  postForEntity(createPersonUrl, request, Person.class);
assertNotNull(responseEntityPerson.getBody());
assertNotNull(responseEntityPerson.getBody().getName());

2.3. 使用postForLocation发送json

与postForObject 和 postForEntity 方法类型, postForLocation 也发送post请求至特定uri并创建新的对象。唯一的差异是返回值为Location头信息。

前面updatePerson rest api在响应中设置Location 头信息:

response.setHeader("Location", ServletUriComponentsBuilder.fromCurrentContextPath()
  .path("/findPerson/" + person.getId()).toUriString());

现在我们需要实现更新person对象后接收返回带有Location头信息的响应,使用postForLocation 方法:

@Test
public void givenDataIsJson_whenDataIsPostedByPostForLocation_thenResponseBodyIsTheLocationHeader() 
  throws JsonProcessingException {
    HttpEntity<String> request = new HttpEntity<String>(personJsonObject.toString(), headers);
    URI locationHeader = restTemplate.postForLocation(updatePersonUrl, request);
    assertNotNull(locationHeader);

3. 总结

本文讲解了RestTemplate 如何发送json类型的post请求,共三种方法应用与不同场景。

RestTemplate使用JSON发送Post请求本文我们说下如何使用Spring的 RestTemplate调用post请求,发送json内容。1. 定义服务端web接口1.1. 定义业务接口先定义Person实体类表示post请求的数据:public class Person { private Integer id; private String name; ... 传统情况下在java代码里访问restful服务,一般使用Apache的HttpClient。不过此种方法使用起来太过繁琐。spring提供了一种简单便捷的模板类来进行操作,这就是RestTemplate。 二、添加header 在我们向服务端发送请求时,还必须向服务器发送一个叫“Content-Length”的请求头(Request Header)。 作用:在header中... 代码片段供参考: public Boolean getSalesInfoByUpdateTime(String startTime,String endTime) { String salesinfoUrl = "http://----------------" //设置消息头 HttpHeaders head 二者的主要区别在于,postForObject()返回值是HTTP协议的响应体。postForEntity()返回的是ResponseEntity,ResponseEntity是对HTTP响应的封装,除了包含响应体,还包含HTTP状态码、contentType、contentLength、Header等信息。 一、post
使用RestTemplate进行http请求时,的确很方便,但是当需要进行post请求时遇到了坑 1POST传递参数 :采用 LinkedMultiValueMap ,不能使用HashMap String url = 'http://posturl'; MultiValueMap<String, String> map= new LinkedMultiValueMap&lt......
private RestTemplate getRestTemplate() { RestTemplate restTemplate = new RestTemplate(); ExtendMappingJackson2HttpMessageConverter convert = new ExtendMappingJackson2HttpMessageConverter(); convert.setObjectMapper(new...
postForEntity() 二者的主要区别在于,postForObject()返回值是HTTP协议的响应体。postForEntity()返回的是ResponseEntity,ResponseEntity是对HTTP响应的封装,除了包含响应体,还包含HTTP状态码、contentType、contentLength、Header等信息。 由于缺少经验,传入一个body,但是在return时不是json格式,导致无法响应的问题,如下: public GlobalMessage test(TestBody body){ return restTemplate.postForEntity("http://testDemo/test", body, Globa 1 RestTemplate restTemplate = new RestTemplate(); 2 HttpHeaders headers = new HttpHeaders(); 3 MediaType type = MediaType.parseMediaType("application/jso.
因项目的需要,PHP调用第三方 Java/.Net 写好的 Restful Api,其中有些接口,需要 在发送 POST 请求时,传入对象。 Http中传输对象,最好的表现形式莫过于JSON字符串了,但是作为参数的接收方,又是需要被告知传过来的是JSON! 其实这不难,只需要发送一个 http Content-Type头信息即可,即 “Content-Type: application/json; charset=utf-8”,参考代码如下: * PHP发送Json对象数据 * @param $url 请求url * @param $jsonStr 发送的js
笔者最近用图灵V2版本,V2跟V1版比起来,很大的区别是网络请求,V1版只需一条网址链接即可请求数据,V2版本则需要以请求参数格式为 jsonpost请求数据,无疑增大了难度 打开图灵官网API V2.0接入文档 文档给我们提供了请求示例和返回示例,看着数据十分复杂,复杂的数据就不必用android原生的json解析方式了,因为很容易出错。这里用谷歌的神器gson以及它的插件GsonFormat...
```java import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.client.RestTemplate; public class RestClient { public static void main(String[] args) { // 创建RestTemplate实例 RestTemplate restTemplate = new RestTemplate(); // 设置请求头,指定Content-Type为application/json HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); // 设置请求体,即要发送JSON数据 String jsonBody = "{\"key\": \"value\"}"; // 创建HttpEntity对象,包含请求头和请求体 HttpEntity<String> requestEntity = new HttpEntity<>(jsonBody, headers); // 发送POST请求并获取响应 String url = "http://example.com/api/endpoint"; // 请求的URL String response = restTemplate.postForObject(url, requestEntity, String.class); // 处理响应 System.out.println(response); 在上面的代码中,您需要将`http://example.com/api/endpoint`替换为实际的目标URL。另外,您可以根据需要调整JSON请求体的内容。