SpringBoot RestTemplate 发起网络请求

下面总结一下SpringBoot项目使用RestTemplate发送网络请求

一、介绍

RestTemple是Spring提供的用于访问Http请求的客户端,RestTemple提供了多种简洁的远程访问服务的方法,省去了很多无用的代码。RestTemplate提供更高等级的符合HTTP的六种主要方法,可以很简单的调用RESTful服务。

二、使用

1:创建RestTemplate

默认配置

@Configuration
public class RestTempleConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

简单配置

    @Bean(name = "restTemplate")
    public RestTemplate restTemplate(@Qualifier("simpleClientHttpRequestFactory") HttpComponentsClientHttpRequestFactory factory) {
        RestTemplate restTemplate = new RestTemplate(factory);
        // 使用 utf-8 编码集的 conver 替换默认的 conver(默认的 string conver 的编码集为"ISO-8859-1")
        List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
        Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();
        while (iterator.hasNext()) {
            HttpMessageConverter<?> converter = iterator.next();
            if (converter instanceof StringHttpMessageConverter) {
                iterator.remove();
            }
        }
        messageConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        // 默认的 RestTemplate 有个机制是请求状态码非200 就抛出异常,会中断接下来的操作。如果不想中断对结果数据得解析,可以通过覆盖默认的 ResponseErrorHandler
        restTemplate.setErrorHandler(new ResponseErrorHandler() {
            @Override
            public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
                return !clientHttpResponse.getStatusCode().is2xxSuccessful();
            }

            @Override
            public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
            }
        });
        return restTemplate;
    }

    @Bean(name = "simpleClientHttpRequestFactory")
    public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        // 建立连接所用的时间
        factory.setReadTimeout(12000);//单位为ms
        // 建立连接后从服务器读取到可用资源所用的时间
        factory.setConnectTimeout(12000);//单位为ms
        // 设置代理
        // setProxy(new java.net.Proxy(java.net.Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8888)));
        return factory;
    }

配置支持https

    @Bean(name = "restTemplate")
    public RestTemplate restTemplate(@Qualifier("httpsFactory") HttpComponentsClientHttpRequestFactory factory) {
        RestTemplate restTemplate = new RestTemplate(factory);
        // 使用 utf-8 编码集的 conver 替换默认的 conver(默认的 string conver 的编码集为"ISO-8859-1")
        List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
        Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();
        while (iterator.hasNext()) {
            HttpMessageConverter<?> converter = iterator.next();
            if (converter instanceof StringHttpMessageConverter) {
                iterator.remove();
            }
        }
        messageConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        // 默认的 RestTemplate 有个机制是请求状态码非200 就抛出异常,会中断接下来的操作。如果不想中断对结果数据得解析,可以通过覆盖默认的 ResponseErrorHandler
        restTemplate.setErrorHandler(new ResponseErrorHandler() {
            @Override
            public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
                return !clientHttpResponse.getStatusCode().is2xxSuccessful();
            }

            @Override
            public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
            }
        });
        return restTemplate;
    }

    @Bean(name = "httpsFactory")
    public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory() {
        try {
            CloseableHttpClient httpClient = HttpClientUtils.acceptsUntrustedCertsHttpClient();
            HttpComponentsClientHttpRequestFactory httpsFactory =
                    new HttpComponentsClientHttpRequestFactory(httpClient);
            httpsFactory.setReadTimeout(20000); // 建立连接所用的时间
            httpsFactory.setConnectTimeout(20000);// 建立连接后从服务器读取到可用资源所用的时间
            return httpsFactory;
        } catch (Exception e) {
            log.info(e.getMessage());
            return null;
        }
    }

// HttpClientUtils类
public static CloseableHttpClient acceptsUntrustedCertsHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        // 异常重试次数3次
        HttpClientBuilder b = HttpClientBuilder.create().setRetryHandler(new DefaultHttpRequestRetryHandler(3, false));
//        HttpClientBuilder b = HttpClientBuilder.create();

        // 设置允许所有证书的信任策略
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                return true;
            }
        }).build();
        b.setSSLContext(sslContext);

        // 忽略主机名检查
        // use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken
        HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;

        // 以下是特殊部分:
        // 需要创建SSL套接字工厂,用我们弱化的“信任策略”;并创建一个注册表,来注册它。
        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", sslSocketFactory)
                .build();

        // 现在,我们使用注册表创建连接管理器。
        // 允许多线程使用
        PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        connMgr.setMaxTotal(200);// 连接池最大连接数
        connMgr.setDefaultMaxPerRoute(100);// 每个主机的并发
        b.setConnectionManager(connMgr);
//        b.setProxy(new HttpHost("127.0.0.1", 8888));
        // 最后,构建HttpClient;
        CloseableHttpClient client = b.build();

        return client;
    }

2:使用

常用方法

    getForEntity() 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象

    getForObject() 发送一个HTTP GET请求,返回的请求体将映射为一个对象

    postForEntity() POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得
到的

    postForObject() POST 数据到一个URL,返回根据响应体匹配形成的对象

    delete() 在特定的URL上对资源执行HTTP DELETE操作

    exchange() 在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中
映射得到的

    execute() 在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象

    headForHeaders() 发送HTTP HEAD请求,返回包含特定资源URL的HTTP头

    optionsForAllow() 发送HTTP OPTIONS请求,返回对特定URL的Allow头信息

    postForLocation() POST 数据到一个URL,返回新创建资源的URL

    put() PUT 资源到特定的URL

// GET请求
ResponseEntity<List> responseEntity = restTemplate.getForEntity("http://localhost/getAll", List.class)
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://localhost/get/{id}", String.class, id)

// GET带参数请求
HashMap<String, String> map = new HashMap<>();
map.put("id",id);
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://localhost/get/{id}", String.class, map)

// POST请求
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/save", entity, String.class);
// POST带参数
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/saveByType/{type}", entity, String.class, type);
// POST多参数
HashMap<String, String> map = new HashMap<>();
map.put("type", type);
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost/saveByType/{type}", entity, String.class,map);

发送带请求头的请求

// GET
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity(null);
            UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://xxxx");
            for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                builder.queryParam(entry.getKey(), entry.getValue());
            }
// url地址中有特殊的转义字符,如果使用resttemplate的方法的话,其默认会进行转义%=>%25使用builder.build(true).toUri()可以使其不被转义
            ResponseEntity<XxxDTO> re = restTemplate.exchange(builder.build(true).toUri(), HttpMethod.GET, request, XxxDTO.class);

// POST form
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); // 默认方式可不设置
MultiValueMap<String, Object> requestMap = new LinkedMultiValueMap<String, Object>();
for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
    requestMap.add(entry.getKey(), entry.getValue());
}
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<MultiValueMap<String, Object>>(requestMap, headers);
ResponseEntity<XxxDTO> re = restTemplate.postForEntity("http://xxx", requestEntity, XxxDTO.class);

// POST JSON
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
HashMap<String, Object> params = new HashMap<>();

// String jsonStr = JSONUtil.toJsonStr(paramDTO);
// HttpEntity<String> requestEntity= new HttpEntity<String>(jsonStr , headers);

// JSONObject json = new JSONObject();
// json.put("key", "");
// HttpEntity<String> requestEntity = new HttpEntity<String>(json.toString(), headers);

params.put("name", name);
HttpEntity requestEntity= new HttpEntity<>(params, headers);
ResponseEntity<XxxDTO> re = restTemplate.postForEntity("http://xxx", requestEntity, XxxDTO.class);

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值