RestTemplate 简单使用

1年前 (2022) 程序员胖胖胖虎阿
144 0 0

目录

引用:

简述

 一、环境配置

1.1 非 Spring 环境下使用 RestTemplate

注意:

1.2、Spring 环境下使用 RestTemplate

二、API 实践

2.1、GET 请求

不带参的get请求

带参的get请求(restful风格)

带参的get请求(使用占位符号传参)

2.2、POST 请求

模拟表单请求,post方法测试

模拟表单请求,post方法测试(对象接受)

模拟 JSON 请求,post 方法测试

模拟页面重定向,post请求

2.3、PUT 请求 

2.4、DELETE 请求

2.5、通用请求方法 exchange 方法

2.6、excute()指定调用方式

注意:

2.6 手动指定转换器(HttpMessageConverter)

2.7 设置底层连接方式

2.8 设置拦截器(ClientHttpRequestInterceptor)


引用

引用了很多作者的内容,有一小部分是自己添加的 ,原文在这里:

真不是我吹,Spring里这款牛逼的网络工具库我估计你都没用过!

Springboot — 用更优雅的方式发HTTP请求(RestTemplate详解) - 云+社区 - 腾讯云

RestTemplate - 简书

简述

 RestTemplate 是一个执行HTTP请求的同步阻塞式工具类,它仅仅只是在 HTTP 客户端库(例如 JDK HttpURLConnection,Apache HttpComponents,okHttp 等)基础上,封装了更加简单易用的模板方法 API,方便程序员利用已提供的模板方法发起网络请求和处理,能很大程度上提升我们的开发效率。 

 是Spring用于同步client端的核心类,简化了与http服务的通信,并满足RestFul原则,程序代码可以给它提供URL,并提取结果。默认情况下,RestTemplate默认依赖jdk的HTTP连接工具。当然你也可以 通过setRequestFactory属性切换到不同的HTTP源,比如Apache HttpComponents、Netty和OkHttp。

 一、环境配置

1.1 非 Spring 环境下使用 RestTemplate

如果当前项目不是Spring项目,加入spring-web包,即可引入RestTemplate

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>5.2.6.RELEASE</version>
</dependency>

编写一个单元测试类,使用RestTemplate发送一个GET请求,看看程序运行是否正常

@Test
public void simpleTest() {
    RestTemplate restTemplate = new RestTemplate();
    String url = "http://jsonplaceholder.typicode.com/posts/1";
    String str = restTemplate.getForObject(url, String.class);
    System.out.println(str);
}

注意:

RestTemplate 使用 转换器(HttpMessageConverter) 来处理请求数据和返回数据, 非 Spring 环境下有些包不全,会导致某些转换器不可用,例如将 javabean转换为json的 MappingJackson2XmlHttpMessageConverter 转换器, 所以要使用所有转换器的话需要额外添加这些转换器依赖的包,Spring环境的依赖包是包含这些缺失包的,不用额外添加

         <!--  HttpMessageConverter :  MappingJackson2HttpMessageConverter-->
 
        <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-databind</artifactId>
           <version>2.13.1</version>
       </dependency>
       <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-annotations</artifactId>
           <version>2.13.1</version>
       </dependency>

       <dependency>
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-core</artifactId>
           <version>2.13.1</version>
       </dependency>


        <!-- HttpMessageConverter : MappingJackson2XmlHttpMessageConverter -->
       <dependency>
           <groupId>com.fasterxml.jackson.dataformat</groupId>
           <artifactId>jackson-dataformat-xml</artifactId>
           <version>2.13.1</version>
       </dependency>

具体是那些转换器和这些转换器缺什么包,可以移步源码:

// 文件:  RestTemplate.java
// 行数: 137行

package org.springframework.web.client;

public RestTemplate() {
		this.messageConverters.add(new ByteArrayHttpMessageConverter());
		this.messageConverters.add(new StringHttpMessageConverter());
		this.messageConverters.add(new ResourceHttpMessageConverter(false));
		try {
			this.messageConverters.add(new SourceHttpMessageConverter<>());
		}
		catch (Error err) {
			// Ignore when no TransformerFactory implementation is available
		}
		this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());

		if (romePresent) {
			this.messageConverters.add(new AtomFeedHttpMessageConverter());
			this.messageConverters.add(new RssChannelHttpMessageConverter());
		}

		if (jackson2XmlPresent) {
			this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
		}
		else if (jaxb2Present) {
			this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
		}

		if (jackson2Present) {
			this.messageConverters.add(new MappingJackson2HttpMessageConverter());
		}
		else if (gsonPresent) {
			this.messageConverters.add(new GsonHttpMessageConverter());
		}
		else if (jsonbPresent) {
			this.messageConverters.add(new JsonbHttpMessageConverter());
		}

		if (jackson2SmilePresent) {
			this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter());
		}
		if (jackson2CborPresent) {
			this.messageConverters.add(new MappingJackson2CborHttpMessageConverter());
		}

		this.uriTemplateHandler = initUriTemplateHandler();
	}

1.2、Spring 环境下使用 RestTemplate

如果当前项目是SpringBoot,添加如下依赖接口!

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

同时,将RestTemplate配置初始化为一个Bean

@Configuration
public class RestTemplateConfig {

    /**
     * 没有实例化RestTemplate时,初始化RestTemplate
     * @return
     */
    @ConditionalOnMissingBean(RestTemplate.class)
    @Bean
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }
}

注意,这种初始化方法,是使用了JDK自带的HttpURLConnection作为底层HTTP客户端实现。

当然,我们还可以修改RestTemplate默认的客户端,例如将其改成HttpClient客户端,方式如下:

@Configuration
public class RestTemplateConfig {


    /**
     * 没有实例化RestTemplate时,初始化RestTemplate
     * @return
     */
    @ConditionalOnMissingBean(RestTemplate.class)
    @Bean
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
        return restTemplate;
    }

    /**
     * 使用HttpClient作为底层客户端
     * @return
     */
    private ClientHttpRequestFactory getClientHttpRequestFactory() {
        int timeout = 5000;
        RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(timeout)
                .setConnectionRequestTimeout(timeout)
                .setSocketTimeout(timeout)
                .build();
        CloseableHttpClient client = HttpClientBuilder
                .create()
                .setDefaultRequestConfig(config)
                .build();
        return new HttpComponentsClientHttpRequestFactory(client);
    }

}

在需要使用RestTemplate的位置,注入并使用即可!

@Autowired
private RestTemplate restTemplate;

从开发人员的反馈,和网上的各种HTTP客户端性能以及易用程度评测来看,OkHttp 优于 ApacheHttpClientApacheHttpClient优于HttpURLConnection

因此,我们还可以通过如下方式,将底层的http客户端换成OkHttp

/**
 * 使用OkHttpClient作为底层客户端
 * @return
 */
private ClientHttpRequestFactory getClientHttpRequestFactory(){
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .connectTimeout(5, TimeUnit.SECONDS)
            .writeTimeout(5, TimeUnit.SECONDS)
            .readTimeout(5, TimeUnit.SECONDS)
            .build();
    return new OkHttp3ClientHttpRequestFactory(okHttpClient);
}

二、API 实践

RestTemplate最大的特色就是对各种网络请求方式做了包装,能极大的简化开发人员的工作量,下面我们以GETPOSTPUTDELETE文件上传与下载为例,分别介绍各个API的使用方式!

2.1、GET 请求

通过RestTemplate发送HTTP GET协议请求,经常使用到的方法有两个:

  • getForObject()

  • getForEntity()

二者的主要区别在于,getForObject()返回值是HTTP协议的响应体。

getForEntity()返回的是ResponseEntityResponseEntity是对HTTP响应的封装,除了包含响应体,还包含HTTP状态码、contentTypecontentLengthHeader等信息。

Spring Boot环境下写一个单元测试用例,首先创建一个Api接口,然后编写单元测试进行服务测试。

  • 不带参的get请求

@RestController
public class TestController {

    /**
     * 不带参的get请求
     * @return
     */
    @RequestMapping(value = "testGet", method = RequestMethod.GET)
    public ResponseBean testGet(){
        ResponseBean result = new ResponseBean();
        result.setCode("200");
        result.setMsg("请求成功,方法:testGet");
        return result;
    }
}
public class ResponseBean {

    private String code;

    private String msg;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "ResponseBean{" +
                "code='" + code + '\'' +
                ", msg='" + msg + '\'' +
                '}';
    }
}
@Autowired
private RestTemplate restTemplate;

/**
 * 单元测试(不带参的get请求)
 */
@Test
public void testGet(){
    //请求地址
    String url = "http://localhost:8080/testGet";

    //发起请求,直接返回对象
    ResponseBean responseBean = restTemplate.getForObject(url, ResponseBean.class);
    System.out.println(responseBean.toString());
}
  • 带参的get请求(restful风格)

@RestController
public class TestController {

    /**
     * 带参的get请求(restful风格)
     * @return
     */
    @RequestMapping(value = "testGetByRestFul/{id}/{name}", method = RequestMethod.GET)
    public ResponseBean testGetByRestFul(@PathVariable(value = "id") String id, @PathVariable(value = "name") String name){
        ResponseBean result = new ResponseBean();
        result.setCode("200");
        result.setMsg("请求成功,方法:testGetByRestFul,请求参数id:" +  id + "请求参数name:" + name);
        return result;
    }
}
@Autowired
private RestTemplate restTemplate;


 /**
 * 单元测试(带参的get请求)
 */
@Test
public void testGetByRestFul(){
    //请求地址
    String url = "http://localhost:8080/testGetByRestFul/{1}/{2}";

    //发起请求,直接返回对象(restful风格)
    ResponseBean responseBean = restTemplate.getForObject(url, ResponseBean.class, "001", "张三");
    System.out.println(responseBean.toString());
}
  • 带参的get请求(使用占位符号传参)

@RestController
public class TestController {

    /**
     * 带参的get请求(使用占位符号传参)
     * @return
     */
    @RequestMapping(value = "testGetByParam", method = RequestMethod.GET)
    public ResponseBean testGetByParam(@RequestParam("userName") String userName,
                                             @RequestParam("userPwd") String userPwd){
        ResponseBean result = new ResponseBean();
        result.setCode("200");
        result.setMsg("请求成功,方法:testGetByParam,请求参数userName:" +  userName + ",userPwd:" + userPwd);
        return result;
    }
}
@Autowired
private RestTemplate restTemplate;

 /**
 * 单元测试(带参的get请求)
 */
@Test
public void testGetByParam(){
    //请求地址
    String url = "http://localhost:8080/testGetByParam?userName={userName}&userPwd={userPwd}";

    //请求参数
    Map<String, String> uriVariables = new HashMap<>();
    uriVariables.put("userName", "唐三藏");
    uriVariables.put("userPwd", "123456");

    //发起请求,直接返回对象(带参数请求)
    ResponseBean responseBean = restTemplate.getForObject(url, ResponseBean.class, uriVariables);
    System.out.println(responseBean.toString());
}

上面的所有的getForObject请求传参方法,getForEntity都可以使用,使用方法上也几乎是一致的,只是在返回结果接收的时候略有差别。

使用ResponseEntity<T> responseEntity来接收响应结果。用responseEntity.getBody()获取响应体。

 /**
 * 单元测试
 */
@Test
public void testAllGet(){
    //请求地址
    String url = "http://localhost:8080/testGet";

    //发起请求,返回全部信息
    ResponseEntity<ResponseBean> response = restTemplate.getForEntity(url, ResponseBean.class);

    // 获取响应体
    System.out.println("HTTP 响应body:" + response.getBody().toString());

    // 以下是getForEntity比getForObject多出来的内容
    HttpStatus statusCode = response.getStatusCode();
    int statusCodeValue = response.getStatusCodeValue();
    HttpHeaders headers = response.getHeaders();

    System.out.println("HTTP 响应状态:" + statusCode);
    System.out.println("HTTP 响应状态码:" + statusCodeValue);
    System.out.println("HTTP Headers信息:" + headers);
}

2.2、POST 请求

其实POST请求方法和GET请求方法上大同小异,RestTemplatePOST请求也包含两个主要方法:

  • postForObject()

  • postForEntity()

postForEntity()返回全部的信息,postForObject()方法返回body对象,具体使用方法如下!

  • 模拟表单请求,post方法测试

    @RestController
    public class TestController {
    
        /**
         * 模拟表单请求,post方法测试
         * @return
         */
        @RequestMapping(value = "testPostByForm", method = RequestMethod.POST)
        public ResponseBean testPostByForm(@RequestParam("userName") String userName,
                                            @RequestParam("userPwd") String userPwd){
            ResponseBean result = new ResponseBean();
            result.setCode("200");
            result.setMsg("请求成功,方法:testPostByForm,请求参数userName:" + userName + ",userPwd:" + userPwd);
            return result;
        }
    }
    
    @Autowired
    private RestTemplate restTemplate;
    
    /**
     * 模拟表单提交,post请求
     */
    @Test
    public void testPostByForm(){
        //请求地址
        String url = "http://localhost:8080/testPostByForm";
    
        // 请求头设置,x-www-form-urlencoded格式的数据
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    
        //提交参数设置
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("userName", "唐三藏");
        map.add("userPwd", "123456");
    
        // 组装请求体
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
    
        //发起请求
        ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class);
        System.out.println(responseBean.toString());
    }
    
  • 模拟表单请求,post方法测试(对象接受)

  • @RestController
    public class TestController {
    
        /**
         * 模拟表单请求,post方法测试
         * @param request
         * @return
         */
        @RequestMapping(value = "testPostByFormAndObj", method = RequestMethod.POST)
        public ResponseBean testPostByForm(RequestBean request){
            ResponseBean result = new ResponseBean();
            result.setCode("200");
            result.setMsg("请求成功,方法:testPostByFormAndObj,请求参数:" + JSON.toJSONString(request));
            return result;
        }
    }
    
    public class RequestBean {
    
    
        private String userName;
    
    
        private String userPwd;
    
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getUserPwd() {
            return userPwd;
        }
    
        public void setUserPwd(String userPwd) {
            this.userPwd = userPwd;
        }
    }
    
    @Autowired
    private RestTemplate restTemplate;
    
    /**
     * 模拟表单提交,post请求
     */
    @Test
    public void testPostByForm(){
        //请求地址
        String url = "http://localhost:8080/testPostByFormAndObj";
    
        // 请求头设置,x-www-form-urlencoded格式的数据
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    
        //提交参数设置
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("userName", "唐三藏");
        map.add("userPwd", "123456");
    
        // 组装请求体
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
    
        //发起请求
        ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class);
        System.out.println(responseBean.toString());
    }
    
  • 模拟 JSON 请求,post 方法测试

  • @RestController
    public class TestController {
    
        /**
         * 模拟JSON请求,post方法测试
         * @param request
         * @return
         */
        @RequestMapping(value = "testPostByJson", method = RequestMethod.POST)
        public ResponseBean testPostByJson(@RequestBody RequestBean request){
            ResponseBean result = new ResponseBean();
            result.setCode("200");
            result.setMsg("请求成功,方法:testPostByJson,请求参数:" + JSON.toJSONString(request));
            return result;
        }
    }
    
    @Autowired
    private RestTemplate restTemplate;
    
    /**
     * 模拟JSON提交,post请求
     */
    @Test
    public void testPostByJson(){
        //请求地址
        String url = "http://localhost:8080/testPostByJson";
    
        //入参
        RequestBean request = new RequestBean();
        request.setUserName("唐三藏");
        request.setUserPwd("123456789");
    
       
        //发送post请求,并打印结果,以String类型接收响应结果JSON字符串
        ResponseBean responseBean = restTemplate.postForObject(url, request, ResponseBean.class);
        System.out.println(responseBean.toString());
    }
    
  • 模拟页面重定向,post请求

  • @Controller
    public class LoginController {
    
        /**
         * 重定向
         * @param request
         * @return
         */
        @RequestMapping(value = "testPostByLocation", method = RequestMethod.POST)
        public String testPostByLocation(@RequestBody RequestBean request){
            return "redirect:index.html";
        }
    }
    
    
    @Autowired
    private RestTemplate restTemplate;
    
    /**
     * 重定向,post请求
     */
    @Test
    public void testPostByLocation(){
        //请求地址
        String url = "http://localhost:8080/testPostByLocation";
    
        //入参
        RequestBean request = new RequestBean();
        request.setUserName("唐三藏");
        request.setUserPwd("123456789");
    
        //用于提交完成数据之后的页面跳转,返回跳转url
        URI uri = restTemplate.postForLocation(url, request);
        System.out.println(uri.toString());
    }
    

    输出结果如下:

    http://localhost:8080/index.html

2.3、PUT 请求 

put请求方法,可能很多人都没用过,它指的是修改一个已经存在的资源或者插入资源,该方法会向URL代表的资源发送一个HTTP PUT方法请求,示例如下!

@RestController
public class TestController {

    /**
     * 模拟JSON请求,put方法测试
     * @param request
     * @return
     */
    @RequestMapping(value = "testPutByJson", method = RequestMethod.PUT)
    public void testPutByJson(@RequestBody RequestBean request){
        System.out.println("请求成功,方法:testPutByJson,请求参数:" + JSON.toJSONString(request));
    }
}
@Autowired
private RestTemplate restTemplate;

/**
 * 模拟JSON提交,put请求
 */
@Test
public void testPutByJson(){
    //请求地址
    String url = "http://localhost:8080/testPutByJson";

    //入参
    RequestBean request = new RequestBean();
    request.setUserName("唐三藏");
    request.setUserPwd("123456789");

    //模拟JSON提交,put请求
    restTemplate.put(url, request);
}

2.4、DELETE 请求

与之对应的还有delete方法协议,表示删除一个已经存在的资源,该方法会向URL代表的资源发送一个HTTP DELETE方法请求。

@RestController
public class TestController {

    /**
     * 模拟JSON请求,delete方法测试
     * @return
     */
    @RequestMapping(value = "testDeleteByJson", method = RequestMethod.DELETE)
    public void testDeleteByJson(){
        System.out.println("请求成功,方法:testDeleteByJson");
    }
}
@Autowired
private RestTemplate restTemplate;

/**
 * 模拟JSON提交,delete请求
 */
@Test
public void testDeleteByJson(){
    //请求地址
    String url = "http://localhost:8080/testDeleteByJson";

    //模拟JSON提交,delete请求
    restTemplate.delete(url);
}

2.5、通用请求方法 exchange 方法

如果以上方法还不满足你的要求。在RestTemplate工具类里面,还有一个exchange通用协议请求方法,它可以发送GETPOSTDELETEPUTOPTIONSPATCH等等HTTP方法请求。

示例:

@Test
    public void rtExchangeTest() throws JSONException {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://xxx.top/notice/list";
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        JSONObject jsonObj = new JSONObject();
        jsonObj.put("start",1);
        jsonObj.put("page",5);
 
        HttpEntity<String> entity = new HttpEntity<>(jsonObj.toString(), headers);
        ResponseEntity<JSONObject> exchange = restTemplate.exchange(url,
                                          HttpMethod.GET, entity, JSONObject.class);
        System.out.println(exchange.getBody());
    }

2.6、excute()指定调用方式

excute()的用法与exchange()大同小异了,它同样可以指定不同的HttpMethod,不同的是它返回的对象是响应体所映射成的对象,而不是ResponseEntity。

需要强调的是,execute()方法是以上所有方法的底层调用。随便看一个:

@Override
    @Nullable
    public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
            throws RestClientException {
 
        RequestCallback requestCallback = httpEntityCallback(request, responseType);
        HttpMessageConverterExtractor<T> responseExtractor =
                new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
        return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);
    }

注意:

restTemplate.postForEntity等方法虽然表面上接收的request是@Nullable Object request类型,但是你追踪下去会发现,这个request是用HttpEntity来解析,所以就直接使用HttpEntity.

核心代码如下:

//文件: RestTemplate.java
//行数: 899

package org.springframework.web.client;

public HttpEntityRequestCallback(@Nullable Object requestBody, @Nullable Type responseType) {
			super(responseType);
			if (requestBody instanceof HttpEntity) {
				this.requestEntity = (HttpEntity<?>) requestBody;
			}
			else if (requestBody != null) {
				this.requestEntity = new HttpEntity<>(requestBody);
			}
			else {
				this.requestEntity = HttpEntity.EMPTY;
			}
		}

2.6 手动指定转换器(HttpMessageConverter)

我们知道,调用reseful接口传递的数据内容是json格式的字符串,返回的响应也是json格式的字符串。然而restTemplate.postForObject方法的请求参数RequestBean和返回参数ResponseBean却都是java类。是RestTemplate通过HttpMessageConverter自动帮我们做了转换的操作。

默认情况下RestTemplate自动帮我们注册了一组HttpMessageConverter用来处理一些不同的contentType的请求。
StringHttpMessageConverter来处理text/plain;MappingJackson2HttpMessageConverter来处理application/json;MappingJackson2XmlHttpMessageConverter来处理application/xml
你可以在org.springframework.http.converter包下找到所有spring帮我们实现好的转换器。
如果现有的转换器不能满足你的需求,你还可以实现org.springframework.http.converter.HttpMessageConverter接口自己写一个。详情参考官方api。

选好了HttpMessageConverter后怎么把它注册到我们的RestTemplate中呢。

  RestTemplate restTemplate = new RestTemplate();
        //获取RestTemplate默认配置好的所有转换器
        List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
        //默认的MappingJackson2HttpMessageConverter在第7个 先把它移除掉
        messageConverters.remove(6);
        //添加上GSON的转换器
        messageConverters.add(6, new GsonHttpMessageConverter());

这个简单的例子展示了如何使用GsonHttpMessageConverter替换掉默认用来处理application/jsonMappingJackson2HttpMessageConverter

2.7 设置底层连接方式

要创建一个RestTemplate的实例,您可以像上述例子中简单地调用默认的无参数构造函数。这将使用java.net包中的标准Java类作为底层实现来创建HTTP请求。
但很多时候我们需要像传统的HttpClient那样设置HTTP请求的一些属性。RestTemplate使用了一种很偷懒的方式实现了这个需求,那就是直接使用一个HttpClient作为底层实现......

     //生成一个设置了连接超时时间、请求超时时间、异常最大重试次数的httpClient
        RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(10000).setConnectTimeout(10000).setSocketTimeout(30000).build();
        HttpClientBuilder builder = HttpClientBuilder.create().setDefaultRequestConfig(config).setRetryHandler(new DefaultHttpRequestRetryHandler(5, false));
        HttpClient httpClient = builder.build();
        //使用httpClient创建一个ClientHttpRequestFactory的实现
        ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
         //ClientHttpRequestFactory作为参数构造一个使用作为底层的RestTemplate
        RestTemplate restTemplate = new RestTemplate(requestFactory);

2.8 设置拦截器(ClientHttpRequestInterceptor)

有时候我们需要对请求做一些通用的拦截设置,这就可以使用拦截器进行处理。拦截器需要我们实现org.springframework.http.client.ClientHttpRequestInterceptor接口自己写。

举个简单的例子,写一个在header中根据请求内容和地址添加令牌的拦截器。

public class TokenInterceptor implements ClientHttpRequestInterceptor
{
    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException
    {
        //请求地址
        String checkTokenUrl = request.getURI().getPath();
        //token有效时间
        int ttTime = (int) (System.currentTimeMillis() / 1000 + 1800);
        //请求方法名 POST、GET等
        String methodName = request.getMethod().name();
        //请求内容
        String requestBody = new String(body);
        //生成令牌 此处调用一个自己写的方法,有兴趣的朋友可以自行google如何使用ak/sk生成token,此方法跟本教程无关,就不贴出来了
        String token = TokenHelper.generateToken(checkTokenUrl, ttTime, methodName, requestBody);
        //将令牌放入请求header中
        request.getHeaders().add("X-Auth-Token",token);

        return execution.execute(request, body);
    }
}

创建RestTemplate实例的时候可以这样向其中添加拦截器

 

        RestTemplate restTemplate = new RestTemplate();
        //向restTemplate中添加自定义的拦截器
        restTemplate.getInterceptors().add(new TokenInterceptor());

版权声明:程序员胖胖胖虎阿 发表于 2022年11月10日 上午4:00。
转载请注明:RestTemplate 简单使用 | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...