Title

使用 Spring 的 RestTemplate 发送请求

RestTemplate是什么

RestTemple是Spring提供的用于访问Http请求的客户端,RestTemple提供了多种简洁的远程访问服务的方法,省去了很多无用的代码。

为什么要用RestTemplate

相信大家之前都用过apache的HTTPClient类,逻辑繁琐,代码复杂,还要自己编写使用类HttpClientUtil,封装对应的post,get,delete等方法。

RestTemplate的行为可以通过callback回调方法和配置HttpMessageConverter 来定制,用来把对象封装到HTTP请求体,将响应信息放到一个对象中。RestTemplate提供更高等级的符合HTTP的六种主要方法,可以很简单的调用RESTful服务。

具体使用

GET 无参请求

// 设置请求地址
String sendUrl = "http://192.168.12.11/user/allDAta";
String token = request.getHeader("Authorization");
// 设置请求头
HttpHeaders headers = new HttpHeaders();
// headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", token);
// 设置访问的entity
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<String> result = null;
JSONObject data = null;
try {
    // 发送一个get请求
    result = restTemplate.exchange(sendUrl, HttpMethod.GET, entity, String.class);
    data = JSONObject.parseObject(result.getBody()).getJSONObject("data");
} catch (Exception e) {
    e.printStackTrace();
}
System.out.println(data);

GET 有参请求

// 设置请求地址
String sendUrl = "http://192.168.12.11/user/allDAta";
String token = request.getHeader("Authorization");
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", token);
// 设置访问参数
HashMap<String, Object> params = new HashMap<>(0);
params.put("page", 1);
params.put("size", 10);
// 设置访问的entity
HttpEntity entity = new HttpEntity(params, headers);
ResponseEntity<String> result = null;
JSONObject data = null;
try {
    result = restTemplate.exchange(sendUrl, HttpMethod.GET, entity, String.class);
    data = JSONObject.parseObject(result.getBody()).getJSONObject("data");
} catch (Exception e) {
    e.printStackTrace();
}
System.out.println(data);

POST 参数请求

String sendUrl = "http://192.168.12.11/user/insert";
String token = request.getHeader("Authorization");
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", token);
// 设置请求数据
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>(0);
params.add("username", entity.getUsername());
params.add("password",entity.getPassword());
HttpEntity httpEntity = new HttpEntity(params, headers);
ResponseEntity<String> result = null;
boolean flag = false;
try {
    // 发送一个post请求
    result = restTemplate.exchange(sendUrl, HttpMethod.POST, httpEntity, String.class);
    flag = JSONObject.parseObject(result.getBody()).getBoolean("data");
} catch (Exception e) {
    e.printStackTrace();
}
System.out.println(flag);

POST 实体请求

String sendUrl = "http://192.168.12.11/user/insert";
String token = request.getHeader("Authorization");
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", token);
// 设置请求数据
AddUserVO addUserVO = new AddUserVO();
addUserVO.setUserId(entity.getId());
addUserVO.setUsername(entity.getUsername());
addUserVO.setRealname(entity.getName());
addUserVO.setPassword(entity.getPassword());
addUserVO.setPhone(entity.getTel());
HttpEntity httpEntity = new HttpEntity(JSON.toJSON(addUserVO), headers);
ResponseEntity<String> result = null;
boolean flag = false;
try {
    // 发送一个post请求
    if (StrUtil.isNotBlank(entity.getId())) {
        result = restTemplate.exchange(sendUrl, HttpMethod.PUT, httpEntity, String.class);
        flag = JSONObject.parseObject(result.getBody()).getBoolean("data");
    } else {
        result = restTemplate.exchange(sendUrl, HttpMethod.POST, httpEntity, String.class);
        flag = JSONObject.parseObject(result.getBody()).getBoolean("data");
    }
} catch (Exception e) {
    e.printStackTrace();
}
System.out.println(flag);

PATH 参数请求

String sendUrl = "http://192.168.12.11/user/delete/{id}";
String token = request.getHeader("Authorization");
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", token);
HttpEntity entity = new HttpEntity(headers);
ResponseEntity<String> result = null;
boolean flag = false;
try {
    // {id} 是占位符,请求最后参数对应 占位id
    result = restTemplate.exchange(sendUrl, HttpMethod.DELETE, entity, String.class, id);
    flag = JSONObject.parseObject(result.getBody()).getBoolean("data");
} catch (Exception e) {
    e.printStackTrace();
}
System.out.println(flag);

请求之后,拿到的结果是一个json类型,我们还需要通过fastjson,Jackson等来处理我们的json字符串,获取到我们想要的数据。

封装工具类

package com.zl.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Component
public class SendHttpUtil {
    @Resource
    private RestTemplate restTemplate;

    /**
     * GET 无参请求
     */
    public ResponseEntity<String> getRequestNoParams(String httpUrl, Map<String, String> headerParams) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        setHeaderParams(headers, headerParams);
        HttpEntity httpEntity = new HttpEntity(headers);
        ResponseEntity<String> data = null;
        try {
            data = restTemplate.exchange(httpUrl, HttpMethod.GET, httpEntity, String.class);
            // 获取 JSONObject.parseObject(data.getBody());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * GET 有参请求
     */
    public ResponseEntity<String> getRequestParams(String httpUrl, Map<String, String> headerParams, HashMap<String, Object> requestParams) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        setHeaderParams(headers, headerParams);
        HttpEntity httpEntity = new HttpEntity(requestParams, headers);
        ResponseEntity<String> data = null;
        try {
            data = restTemplate.exchange(httpUrl, HttpMethod.GET, httpEntity, String.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * POST 参数请求
     */
    public ResponseEntity<String> postRequestParams(String httpUrl, Map<String, String> headerParams, MultiValueMap<String, Object> requestParams) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        setHeaderParams(headers, headerParams);
        HttpEntity httpEntity = new HttpEntity(requestParams, headers);
        ResponseEntity<String> data = null;
        try {
            data = restTemplate.exchange(httpUrl, HttpMethod.POST, httpEntity, String.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * POST 实体请求
     */
    public ResponseEntity<String> postRequestEntity(String httpUrl, Map<String, String> headerParams, Object entity) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        setHeaderParams(headers, headerParams);
        HttpEntity httpEntity = new HttpEntity(JSON.toJSON(entity), headers);
        ResponseEntity<String> data = null;
        try {
            data = restTemplate.exchange(httpUrl, HttpMethod.POST, httpEntity, String.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * PATH 参数请求
     */
    public ResponseEntity<String> pathRequestParams(String httpUrl, Map<String, String> headerParams, Object requestParams) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        setHeaderParams(headers, headerParams);
        HttpEntity httpEntity = new HttpEntity(headers);
        ResponseEntity<String> data = null;
        try {
            data = restTemplate.exchange(httpUrl, HttpMethod.GET, httpEntity, String.class, requestParams);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    private void setHeaderParams(HttpHeaders headers, Map<String, String> headerParams) {
        if (headerParams != null) {
            Set<String> headerKeys = headerParams.keySet();
            headerKeys.stream().forEach(a -> {
                headers.set(a, headerParams.get(a));
            });
        }
    }
}

解决中文乱码

    @Bean
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }

RestTemplate发起HTTPS请求

因为发起HTTPS请求时需要验证服务端SSL证书,所以在此有两种解决办法,一是导入证书,二是忽略证书的校验

这里使用的是忽略证书的校验:

缺少SSLContextBuilder导包:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version> <!-- 请使用最新的稳定版本 -->
</dependency>
  import org.apache.http.conn.ssl.NoopHostnameVerifier;
  import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
  import org.apache.http.conn.ssl.TrustStrategy;
  import org.apache.http.impl.client.CloseableHttpClient;
  import org.apache.http.impl.client.HttpClients;
  import org.apache.http.ssl.SSLContextBuilder;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
  import org.springframework.web.client.RestTemplate;

  import javax.net.ssl.SSLContext;
  import java.security.KeyManagementException;
  import java.security.KeyStoreException;
  import java.security.NoSuchAlgorithmException;
  import java.security.cert.CertificateException;
  import java.security.cert.X509Certificate;

    @Bean(name = "restHttpsTemplate")
    public RestTemplate getRestHttpsTemplate() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        // 信任任何链接,忽略对证书的校验
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                return true;
            }
        }).build();

        // 指定使用的TLS协议版本
//        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext,
//                new String[]{"TLSv1"},
//                null,
//                NoopHostnameVerifier.INSTANCE);

        // NoopHostnameVerifier.INSTANCE 解决No subject alternative names matching IP address xxx.xxx.xxx.xxx found问题
        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);

        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(csf)
                .build();

        HttpComponentsClientHttpRequestFactory requestFactory =
                new HttpComponentsClientHttpRequestFactory();

        requestFactory.setHttpClient(httpClient);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        return restTemplate;
    }

封装

    @Resource(name = "restHttpsTemplate")
    private RestTemplate restHttpsTemplate;


    /**
     * HTTPS POST 实体请求
     */
    public ResponseEntity<String> postHttpsRequestEntity(String httpUrl, Map<String, String> headerParams, Object entity) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        setHeaderParams(headers, headerParams);
        HttpEntity httpEntity = new HttpEntity(JSON.toJSON(entity), headers);
        ResponseEntity<String> data = null;
        try {
            data = restHttpsTemplate.exchange(httpUrl, HttpMethod.POST, httpEntity, String.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

RestTemplate实例和协议不一样,其余的都一样;类比POST即可,这里就不再给出示例了。

posted @ 2022-06-16 19:14  快乐小洋人  阅读(414)  评论(0编辑  收藏  举报