When using SpringBoot, RestTemplate is usually used if you need to invoke a third-party Rest API. Sometimes I don’t know how to pass a parameter, but when the parameter is assigned a value, the receiver receives a null value. This article summarizes some of the most commonly used methods.
The preparatory work
The request object
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private Long id;
private String name;
}
Copy the code
Third Party request
@RestController
public class PersonController {
// Store the relationship between id and person
private static Map<Long, Person> persons = new HashMap<>();
// Generate the ID of person
private static final LongAdder ID_ADDER = new LongAdder();
static {
ID_ADDER.add(1L);
Person person = new Person();
person.setId(ID_ADDER.longValue());
person.setName("1-person"); persons.put(person.getId(), person); }... Omit others}Copy the code
For the third party interface only simple implementation, ignore some details such as parameter verification.
RestTemplate accesses the GET interface
The request parameters are in the path
Third-party interface to query Person by ID
@GetMapping("/getPerson/{id}")
public Person getPersonPathVariable(@PathVariable(name = "id") Long id) {
return persons.getOrDefault(id, new Person());
}
Copy the code
Sample request
Get / / request
URI uri = UriComponentsBuilder.fromUriString(String.format(URL_FORMAT, "/getPerson/{id}")).build(1L);
ResponseEntity<Person> forEntity = REST_TEMPLATE.getForEntity(uri, Person.class);
log.info("getForEntity result:{}", forEntity);
Person forObject = REST_TEMPLATE.getForObject(uri, Person.class);
log.info("getForObject result:{}", forObject);
Copy the code
ResponseEntity in addition to the normal return result, also contains HTTP related information, see the following log.
16:10:48. [the main] INFO 391 com. Yichao. Myblogs. Resttemplate. RestTemplateTest - getForEntity result: < 200, Person (id = 1, name=1-person),[Content-Type:"application/json", Transfer-Encoding:"chunked", Date:"Sat, 15 May 2021 08:10:48 GMT", Keep-Alive:"timeout=60", Connection:"keep-alive"]>Copy the code
Generic request parameter passing, i.e.? name=xxx&id=xxx
Third-party interface to query Person by ID
@GetMapping("/getPerson")
public Person getPersonWithParams(HttpServletRequest httpServletRequest) {
String idStr = httpServletRequest.getParameter("id");
return persons.getOrDefault(Long.valueOf(idStr), new Person());
}
Copy the code
Sample request
Get / / request
URI uri = UriComponentsBuilder.fromUriString(String.format(URL_FORMAT, "/getPerson/{id}")).build(1L);
uri = UriComponentsBuilder.fromUriString(String.format(URL_FORMAT, "/getPerson? id={id}")).build(1L);
ResponseEntity<Person> forEntity = REST_TEMPLATE.getForEntity(uri, Person.class);
log.info("getForEntity result:{}", forEntity);
Person forObject = REST_TEMPLATE.getForObject(uri, Person.class);
log.info("getForObject result:{}", forObject);
Copy the code
RestTemplate accesses the POST interface
The following are distinguished by several different forms of API parameters.
The argument uses @requestBody
Third-party interface that stores the Person passed in and returns the Person object with the primary key added.
@PostMapping("/add/requestBody")
public Person postRequestBody(@RequestBody Person person) {
ID_ADDER.add(1L);
Long id = ID_ADDER.longValue();
person.setId(id);
persons.put(person.getId(), person);
return person;
}
Copy the code
Sample request
String url = String.format(URL_FORMAT, "/add/requestBody");
Person person;
ResponseEntity<Person> responseEntity;
// Generate an object containing only name. The third-party interface is responsible for generating the ID and returning it
Person mockPerson = mockPerson();
person = REST_TEMPLATE.postForObject(url, mockPerson, Person.class);
log.info("requestBody postForObject result:{}", person);
responseEntity = REST_TEMPLATE.postForEntity(url, mockPerson, Person.class);
log.info("requestBody postForEntity result:{}", responseEntity);
Copy the code
Working directly with objects
Third-party Interface
@PostMapping("/add/form")
public Person postForm(Person person) {
ID_ADDER.add(1L);
Long id = ID_ADDER.longValue();
person.setId(id);
persons.put(person.getId(), person);
return person;
}
Copy the code
Sample request
// form request format
String url = String.format(URL_FORMAT, "/add/form");
HttpHeaders headers = new HttpHeaders();
Person mockPerson = mockPerson();
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
// Convert the request object to a map and add it to multiValueMap
@SuppressWarnings("unchecked")
Map<String, Object> params = JSON.parseObject(JSON.toJSONString(mockPerson), Map.class);
params.forEach(map::add);
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(map, headers);
Person person = REST_TEMPLATE.postForObject(url, httpEntity, Person.class);
log.info("form postForObject result:{}", person);
ResponseEntity<Person> responseEntity = REST_TEMPLATE.postForEntity(url, httpEntity, Person.class);
log.info("form postForEntity result{}", responseEntity);
Copy the code
The use of it
Third-party Interface
@PostMapping("/add/requestParam")
public Person postRequestParam(HttpServletRequest httpServletRequest) {
ID_ADDER.add(1L);
String name = httpServletRequest.getParameter("name");
Long id = ID_ADDER.longValue();
Person person = new Person();
person.setId(id);
person.setName(name);
persons.put(person.getId(), person);
return person;
}
Copy the code
Sample request
This method is the same as the form request
String url = String.format(URL_FORMAT, "/add/requestParam");
HttpHeaders headers = new HttpHeaders();
Person mockPerson = mockPerson();
MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
// Convert the request object to a map and add it to multiValueMap
@SuppressWarnings("unchecked")
Map<String, Object> params = JSON.parseObject(JSON.toJSONString(mockPerson), Map.class);
params.forEach(map::add);
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(map, headers);
Person person = REST_TEMPLATE.postForObject(url, httpEntity, Person.class);
log.info("requestParam postForObject result:{}", person);
ResponseEntity<Person> responseEntity = REST_TEMPLATE.postForEntity(url, httpEntity, Person.class);
log.info("requestParam postForEntity result{}", responseEntity);
Copy the code
Advanced usage
Interfaces return generics
Third-party interface that returns a list of Persons
@GetMapping("/listAll")
public List<Person> list(a) {
return new ArrayList<>(persons.values());
}
Copy the code
Sample request
String url = String.format(URL_FORMAT, "listAll");
// Specify the parameter type, which will actually store the returned type
ParameterizedTypeReference<List<Person>> parameterizedTypeReference = new ParameterizedTypeReference<List<Person>>() {
};
ResponseEntity<List<Person>> exchange = REST_TEMPLATE.exchange(url, HttpMethod.GET, null, parameterizedTypeReference);
log.info("testGeneric result:{}", exchange);
List<Person> personList = exchange.getBody();
log.info("person List:{}", personList);
Copy the code
Customized RestTemplate
The following code is used to set some properties of RestTemplate, such as the HTTP connection pool information used by RestTemplate
private static HttpComponentsClientHttpRequestFactory clientHttpRequestFactory(a) {
try {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
// Start setting the connection pool
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
new PoolingHttpClientConnectionManager();
// Maximum number of connections
poolingHttpClientConnectionManager.setMaxTotal(100);
// Number of concurrent routes
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(10);
httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
// Do not retry
httpClientBuilder.setRetryHandler(new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (exception instanceof org.apache.http.NoHttpResponseException) {
// Retry is required in this case
log.warn("No response from server on " + executionCount + " call");
return true;
}
return false; }}); HttpClient httpClient = httpClientBuilder.build(); HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =// httpClient connection configuration
new HttpComponentsClientHttpRequestFactory(httpClient);
// Connection timed out
clientHttpRequestFactory.setConnectTimeout(5000);
// Data read timeout time
clientHttpRequestFactory.setReadTimeout(30000);
// Insufficient connection wait time
clientHttpRequestFactory.setConnectionRequestTimeout(5000);
return clientHttpRequestFactory;
} catch (Exception e) {
log.error("Error initializing HTTP connection pool", e);
}
return null;
}
Copy the code
Set the RestTemplate
new RestTemplateBuilder().requestFactory(() -> clientHttpRequestFactory()).build();
Copy the code
The last
RestTemplate is very powerful, and this article mainly introduces some common features, as well as the previous pit, hoping to help you.