RestTemplate和 apache HttpClient 使用方式

xiaoBai1001發表於2024-07-28

一、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;
        }
    }

相關文章