一、RestTemplate
RestTemplate 是簡化了組裝請求物件 該類存在於 依賴 spring-boot-starter-web中,RestTemplate 支援get,post 現
1、RestTemplate 不是可直接注入Bean, 需要例項化生成Bean
Spring Boot 的自動配置機制非常強大,但並不是所有的類都被預設自動配置為 bean。對於 RestTemplate 來說,Spring Boot 並沒有預設自動配置一個 RestTemplate bean,主要原因有以下幾點:
1)、多樣化的配置需求
2)、鼓勵顯式配置
3)、靈活性和擴充套件性:顯式配置使得應用更加靈活,可以根據需要建立和配置多個不同的
1、簡單方式生成Bean @Configuration public class AppConfig { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } } 2、自定義引數 生成Bean @Configuration public class RestTemplateAutoConfiguration { private final RestTemplateBuilder builder; public RestTemplateAutoConfiguration(RestTemplateBuilder builder) { this.builder = builder; } @Bean public RestTemplate restTemplate() { return builder .setConnectTimeout(Duration.ofSeconds(3)) .setReadTimeout(Duration.ofMillis(PushTaskConstant.DEFAULT_REQUEST_TIME)) .requestFactory(() -> new HttpComponentsClientHttpRequestFactory( HttpClientBuilder.create() .setMaxConnTotal(200) .setMaxConnPerRoute(40) .disableAutomaticRetries() .useSystemProperties().build()) ).build(); } }
2、在重點介紹post請求試
1)請求 當請求型別contentType是MediaType.APPLICATION_FORM_URLENCODED
1、請求方法 @Resource RestTemplate restTemplate; @Test public void testRequest(){ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); // 當請求型別contentType是MediaType.APPLICATION_FORM_URLENCODED,請求引數實體必須是MultiValueMap MultiValueMap<String,String> requestBody=new LinkedMultiValueMap<>(); requestBody.add("userName","testregisterName"); requestBody.add("loginNo","testReg"); requestBody.add("contactPhone","15210212542"); requestBody.add("smsCode","3820"); // 請求和header組合用entity HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(requestBody, headers); ResponseEntity response= restTemplate.postForEntity("http://testapi-xxxx.com/openApp/user/registerUser", entity, String.class); System.out.println("response.getStatusCode() = " + response.getStatusCode()); System.out.println("response.getBody() = " + response.getBody()); } 2、接收方法 public ResultEntity<String> registerUser(RegisterUserRequest userRequest) { }
2)當請求型別contentType是MediaType.APPLICATION_JSON
@Resource RestTemplate restTemplate; @Test public void testRequest2(){ RestTemplate restTemplate = new RestTemplate(); headers.setContentType(MediaType.APPLICATION_JSON); // 當contentType 是APPLICATION_JSON 請求引數物件用map Map<String,String> requestEntity=new HashMap<>(); requestEntity.put("userName","testregisterName"); requestEntity.put("loginNo","testReg"); requestEntity.put("contactPhone","15210212542"); requestEntity.put("smsCode","3820"); // 請求和header組合用entity HttpEntity<Map<String, String>> entity = new HttpEntity<>(requestEntity, headers); ResponseEntity response= restTemplate.postForEntity("http://testapi-console.dmall.com/openApp/user/registerUser", entity, String.class); System.out.println("response.getStatusCode() = " + response.getStatusCode()); System.out.println("response.getBody() = " + response.getBody()); }
ps:已有Bean的注入
1、第一種在配置類中 可以以引數注入 @Configuration public class AppConfig { @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder .setConnectTimeout(Duration.ofMillis(5000)) .setReadTimeout(Duration.ofMillis(5000)) .build(); } -___________________________- 2、也可以正常以屬性注入 @Configuration public class AppConfig { @Resource private RestTemplateBuilder builder; @Bean public RestTemplate restTemplate() { return builder .setConnectTimeout(Duration.ofMillis(5000)) .setReadTimeout(Duration.ofMillis(5000)) .build(); } }
二、 java 8 HttpClient
Apache HttpClient 適合需要更多配置和功能的場景
// 需要引入依賴 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency>
例項呼叫 ps: 使用 httpClient 需要顯示關閉或 try(){} ,try-with-resources 釋放
@Test public void testHttp() throws Exception{ try(CloseableHttpClient httpClient= HttpClients.createDefault()){ HttpPost httpPost=new HttpPost("http://testapi-console.dmall.com/openApp/user/registerUser"); // 可以自定義進行設定 // HttpClients.custom().build() // HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() { // @Override // public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { // if (executionCount >= 3) { // return false; // 超過最大重試次數 // } // if (exception instanceof org.apache.http.NoHttpResponseException) { // return true; // 伺服器無響應 // } // if (exception instanceof java.net.SocketTimeoutException) { // return true; // 超時 // } // return false; // 不重試其他型別的異常 // } // }; // 可以自定義進行配置資訊 RequestConfig requestConfig=RequestConfig.custom() .setConnectTimeout(5000) .setSocketTimeout(5000) .build(); httpPost.setConfig(requestConfig); Map<String,String> parameters=new HashMap<>(); parameters.put("userName","testregisterName"); parameters.put("loginNo","testReg"); parameters.put("contactPhone","15210212542"); parameters.put("smsCode","3820"); StringJoiner stringJoiner=new StringJoiner("&"); for(Map.Entry entry:parameters.entrySet()){ stringJoiner.add(URLEncoder.encode(entry.getKey().toString(),"UTF-8")+"="+URLEncoder.encode(entry.getValue().toString(),"UTF-8")); } // httpPost.setHeader("Content-Type","application/x-www-form-urlencoded"); // httpPost.setEntity(new StringEntity(stringJoiner.toString())); httpPost.setHeader("Content-Type",MediaType.APPLICATION_JSON_VALUE); httpPost.setEntity(new StringEntity(JSON.toJSONString(parameters))); HttpResponse response=httpClient.execute(httpPost); System.out.println("response.getEntity().getContent().toString() = " + response.getEntity().getContent().toString()); String readStr=""; StringBuilder sb=new StringBuilder(); try(BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(response.getEntity().getContent()))){ while ((readStr=bufferedReader.readLine())!=null){ sb.append(readStr); } } System.out.println("stringJoiner = " + sb.toString()); }catch (Exception e){ e.printStackTrace(); throw e; } }