RestTemplate是Spring3.0後開始提供的用於訪問 Rest 服務的輕量級客戶端,相較於傳統的HttpURLConnection、Apache HttpClient、OkHttp等框架,RestTemplate大大簡化了發起HTTP請求以及處理響應的過程。java
RestTemplate只是對其它Rest客戶端的一個封裝,自己並無本身的實現。
不少人都說Spring Boot 2.0以前RestTestTemplate的默認實現是HttpClient,2.+爲OKHttp3,其實這種說法並不徹底正確,若是沒有引入這些客戶端的jar包,其默認實現是HttpURLConnection(集成了URLConnection),這是JDK自帶的REST客戶端實現。web
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.18</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.11.0</version> </dependency>
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.OkHttp3ClientHttpRequestFactory; import org.springframework.web.client.RestTemplate; /** * RestTemplate配置類 */ @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory){ return new RestTemplate(factory); } @Bean public OkHttp3ClientHttpRequestFactory okHttp3ClientHttpRequestFactory(){ OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory(); // 單位:毫秒 factory.setConnectTimeout(10000); factory.setReadTimeout(10000); factory.setWriteTimeout(10000); return factory; } }
@Autowired private RestTemplate restTemplate;
新建User對象,用於下面不一樣請求方式的測試。
構建Http服務。spring
import lombok.Data; @Data public class User { private Long id; private String username; private Integer age; } import com.google.gson.Gson; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/") @Slf4j public class DemoController { @GetMapping("demo/{id}/{userName}") public User get(@PathVariable Long id, @PathVariable String userName, Integer age){ log.info("id:{}, userName:{}, age:{}", id, userName, age); User user = new User(); user.setId(id); user.setUsername(userName); user.setAge(age); return user; } @PostMapping("demo") public User post(@RequestBody String json){ log.info("json:{}", json); Gson gson = new Gson(); User user = gson.fromJson(json, User.class); return user; } }
GET請求對應兩個方法,getForObject()和getForEntity(),每一個方法又對應有具體的三個重載方法。這二者的區別在於getForObject()返回的是一個簡單的對象,而getForEntity()響應的數據中,還額外包含有與HTTP相關的信息,如響應碼、響應頭等。json
//URL中的{id}佔位符最終將會用方法的id參數來填充 String url = "http://127.0.0.1:8083/demo/{id}/{userName}?age=18"; Long id = 1001L; String userName = "Tom"; //重載1:最後一個參數是大小可變的參數列表,每一個參數都會按出現順序插入到指定URL的佔位符中 User user = restTemplate.getForObject(url, User.class, id, userName); System.out.println("user = " + user); //重載2:將id參數放到Map中,並以id做爲key,而後將這個Map做爲最後一個參數 Map<String, Object> urlParams = new HashMap<>(); urlParams.put("id", id); urlParams.put("userName", userName); User user2 = restTemplate.getForObject(url, User.class, urlParams); System.out.println("user2 = " + user2); //重載1:同getForObject(),只不過返回的類型是ResponseEntity ResponseEntity<User> userResponseEntity = restTemplate.getForEntity(url, User.class, id, userName); User user3 = userResponseEntity.getBody(); HttpStatus statusCode = userResponseEntity.getStatusCode(); int statusCodeValue = userResponseEntity.getStatusCodeValue(); HttpHeaders headers = userResponseEntity.getHeaders(); System.out.println("user = " + user3 + "; statusCode = " + statusCode + "; statusCodeValue = " + statusCodeValue + "; headers = " + headers); //重載1:同getForObject(),只不過返回的類型是ResponseEntity Map<String, Object> urlParams2 = new HashMap<>(1); urlParams2.put("id", id); urlParams2.put("userName", userName); ResponseEntity<User> userResponseEntity2 = restTemplate.getForEntity(url, User.class, urlParams2); System.out.println("userResponseEntity2 = " + userResponseEntity2);
POST請求對應三個方法,postForObject()、postForEntity()和postForLocation(),每一個方法一樣對應有三個具體的重載方法。postForObject()、postForEntity()相似於getForObject()和postForEntity(),postForLocation()返回的是一個URI對象。segmentfault
String url = "http://localhost:8083/demo2"; //重載1 & 重載2 User user1 = new User(); user1.setId(12L); user1.setAge(20); user1.setUsername("張三"); //第4個參數能夠是Object... uriVariables 或者 Map<String, ?> uriVariables User u1 = restTemplate.postForObject(url, user1, User.class); System.out.println("user1 = " + u1); //重載3 User user2 = new User(); user2.setId(12L); user2.setAge(30); user2.setUsername("李四"); User u2 = restTemplate.postForObject(URI.create(url), user2, User.class); System.out.println("user2 = " + u2); // 重載1 & 重載2 User user3 = new User(); user3.setAge(25); user3.setUsername("王五"); // 第4個參數能夠是Object... uriVariables 或者 Map<String, ?> uriVariables ResponseEntity<User> userResponseEntity = restTemplate.postForEntity(url, user3, User.class); User userBody = userResponseEntity.getBody(); HttpStatus statusCode = userResponseEntity.getStatusCode(); int statusCodeValue = userResponseEntity.getStatusCodeValue(); HttpHeaders headers = userResponseEntity.getHeaders(); System.out.println("user = " + userBody + "; statusCode = " + statusCode + "; statusCodeValue = " + statusCodeValue + "; headers = " + headers); // 重載3 User user4 = new User(); user4.setAge(35); user4.setUsername("陸六"); ResponseEntity<User> userResponseEntity2 = restTemplate.postForEntity(URI.create(url), user4, User.class); System.out.println("userResponseEntity2 = " + userResponseEntity2);
建議你們多使用exchange()。app
String getUrl = "http://127.0.0.1:8083/demo/{id}/{userName}?age=18"; //GET資源 //參數3是請求頭部分;參數4是響應數據要轉成對象;最後一個參數用於替換URL中的佔位符 ResponseEntity<User> userResponseEntity = restTemplate.exchange(getUrl, HttpMethod.GET, null, User.class, 1001L, "Tom"); System.out.println("exchange = " + userResponseEntity + "; response body = " + userResponseEntity.getBody()); String postUrl = "http://localhost:8083/demo2"; //POST資源 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); String jsonParams = "{\"username\":\"123\",\"age\":23}"; HttpEntity<User> httpEntity = new HttpEntity(jsonParams, headers); ResponseEntity<User> responseEntity = restTemplate.exchange(postUrl, HttpMethod.POST, httpEntity, User.class); System.out.println("exchange = " + responseEntity + "; response body = " + responseEntity.getBody());
String url = "http://localhost:8083/demo2"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); MultiValueMap map = new LinkedMultiValueMap(); map.add("id",1001L); HttpEntity requestBody = new HttpEntity(map, headers); ResponseEntity<User> responseEntity = restTemplate.postForEntity(url, requestBody, User.class); System.out.println(responseEntity.getBody());