RestTemplate

使用RestTemplate来发送Post请求。

包含的方法

1.1 初始化

默认构造函数使用 java.net.HttpURLConnection 来执行请求。您可以使用 ClientHttpRequestFactory 的实现切换到不同的 HTTP 库。有对以下内容的内置支持:

  • Apache HttpComponents
  • Netty
  • OkHttp

例如

RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory());

本例使用Apache 的HttpComponents

1.2 自定义一个RestTemplate对象,并注入到ioc容器

@Configuration
@Slf4j
public class TemplateConfig {
    @Value("${remote.connectTimeout:2000}")
    private int connectTimeout;
    @Value("${remote.readTimeout:30000}")
    private int readTimeout;

    //自定义一个单例的RestTemplate对象
    @Bean
    @Scope("prototype")
    public RestTemplate restTemplate() {
        return new RestTemplate(this.clientHttpRequestFactory());
    }

    @Bean
    public HttpComponentsClientHttpRequestFactory clientHttpRequestFactory() {
        try {
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();

            //构建一个sslContext 
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                    return true;
                }
            }).build();

            httpClientBuilder.setSSLContext(sslContext);
            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
                    hostnameVerifier);

            // 注册http和https请求
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", PlainConnectionSocketFactory.getSocketFactory())
                    .register("https", sslConnectionSocketFactory).build();

            // 开始设置连接池
            PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(
                    socketFactoryRegistry);
            // 最大连接数2700
            poolingHttpClientConnectionManager.setMaxTotal(2700); 
            // 同路由并发数100
            poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);
            httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
            // 重试次数(请求报错后重试次数。0,false表示不重试请求)
            httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false)); 
            
            //创建一个http客户端
            HttpClient httpClient = httpClientBuilder.build();
            // http客户端连接配置
            HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); 
            // 连接超时时间
            clientHttpRequestFactory.setConnectTimeout(connectTimeout); 
            // 数据读取超时时间
            clientHttpRequestFactory.setReadTimeout(readTimeout);
            // 连接不够用的等待时间
            clientHttpRequestFactory.setConnectionRequestTimeout(20000); 
            return clientHttpRequestFactory;
        } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
            log.error("初始化HTTP连接池出错", e);
        }
        return null;
    }
    
}

1.3 使用RestTemplate

此时,RestTemplate对象已经被注入到ioc容器中。直接使用即可。

@Service
@Slf4j
public class SendRequestServiceImpl implements ISendRequestService {
    @Autowired
    private RestTemplate restTemplate;

    @Override
    public void trans(String tranStr) {
        post(tranStr, Url);
    }

    public void post(String sendDataStr, String url) {
        HttpClientBuilder httpClientBuilder = new HttpClientBuilder();
        //MediaType.APPLICATION_JSON:application/json 设置请求体为json格式
        String returnDataString = httpClientBuilder.post4String(restTemplate, url, sendDataStr, MediaType.APPLICATION_JSON);
    }

    public String post4String(RestTemplate restTemplate, String url, String paramStr, MediaType mediaType){
        return RestTemplateHelper.post4String(restTemplate, url, paramStr, mediaType);
    }

    public static String post4String(RestTemplate restTemplate, String url, String paramStr, MediaType mediaType) {
        //设置返回体消息字符编码
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        //设置请求头ContentType为application/json
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(mediaType);
        //新建一个数据传输实体。包括请求头和请求参数(请求体)
        HttpEntity<String> httpEntity = new HttpEntity<>(paramStr, httpHeaders);
        try {
            //发送post请求(url路径,http实体,响应结果类型)
            ResponseEntity<String> result = restTemplate.postForEntity(url, httpEntity, String.class);
            //如果返回码是200,证明http请求成功,将响应结果返回。
            if (HttpStatus.OK == result.getStatusCode()) {
                return result.getBody();
            } else {
                //如果返回码是其他
                log.error("===url("+url+",StatusCode="+result.getStatusCode()+")");
                return "";
            }
        } catch (RestClientException e) {
            //如果请求报错,比如连接超时....
            log.error("===="+e.getMessage()+"===url="+url);
            return ReturnJsonFormat.jsonStr(MyConstants.RETURN_CODE_HTTP_CONNECT_ERROR, MyConstants.RETURN_MSG_HTTP_CONNECT_ERROR);
        }
    }
}
posted @ 2022-01-11 15:16  初夏那片海  阅读(290)  评论(0)    收藏  举报