RestTemplate和 apache HttpClient 使用方式

  高并发请求中需要设置:setMaxConnTotal、setMaxConnPerRoute  两个属性

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

 

 

 

 

posted @ 2024-07-28 10:51  xiaoBai1001  阅读(120)  评论(0编辑  收藏  举报