• HTTP请求-【RestTemplate】


    1、常见的http请求方式

    • RestTemple是Spring提供的用于访问Http请求的客户端
    • Apache的HttpClient
    • 原生HttpURLConnection

    1.1 什么是RestTemple

    【1】RestTemplate是Spring提供的进行远程调用客户端的工具
    【2】调用RestTemplate的默认构造函数时,底层通过使用java.net包下实现创建HTTP请求访问
    【3】RestTemplate创建需要ClientHttpRequestFactory,主要是如下三种(底层执行引擎

    1. SimpleClientHttpRequestFactory 默认实现,使用J2SE提供的方式创建底层的Http请求连接
      RestTemplate restTemplate = new RestTemplate();
    2. HttpComponentsClientHttpRequestFactory 底层使用HttpClient请求http服务
      RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
    3. OkHttp3ClientHttpRequestFactory 底层使用OkHttp访问远程的Http服务

    1.2 HttpMessageConverter

    RestTemplate默认使用HttpMessageConverter进行住消息转换;
    调用restful接口数据传递格式为json,返回数据格式也是json字符串,然而restTemplate.postForObject方法的请求参数和返回参数都是java类,是由于RestTemplate通过HttpMessageConverter自动进行转换

    在创建RestTemplate的时候会默认添加一组HttpMessageConveter的实现。

    【HttpMessageConveter源码】

        public interface HttpMessageConverter<T> {
            //指示此转换器是否可以读取给定的类。
            boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
            //指示此转换器是否可以写给定的类。
            boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
            //返回List
            List<MediaType> getSupportedMediaTypes();
            //读取一个inputMessage
            T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
                throws IOException, HttpMessageNotReadableException;
            //往output message写一个Object
            void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
                throws IOException, HttpMessageNotWritableException;
        }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • StringHttpMessageConverter来处理text/plain;
    • MappingJackson2HttpMessageConverter来处理application/json;
    • MappingJackson2XmlHttpMessageConverter来处理application/xml
    定义转换器HttpMessageConverter如何注册到RestTemplate?
            RestTemplate restTemplate = new RestTemplate();
            //获取RestTemplate默认配置好的所有转换器
            List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
            //默认的MappingJackson2HttpMessageConverter在第7个 先把它移除掉
            messageConverters.remove(6);
            //添加上GSON的转换器,下标从0开始
            messageConverters.add(6, new GsonHttpMessageConverter());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1.3 简单的restful接口实例

    @RestController
    public class TestController
    {
        @RequestMapping(value = "testPost", method = RequestMethod.POST)
        public ResponseBean testPost(@RequestBody RequestBean requestBean)
        {
            ResponseBean responseBean = new ResponseBean();
            responseBean.setRetCode("0000");
            responseBean.setRetMsg("succ");
     
            return responseBean;
        }
    }
    
    使用RestTemplate访问该服务
            //请求地址
            String url = "http://localhost:8080/testPost";
            //入参
            RequestBean requestBean = new RequestBean();
            requestBean.setTest1("1");
            requestBean.setTest2("2");
            requestBean.setTest3("3");
     
            RestTemplate restTemplate = new RestTemplate();
            ResponseBean responseBean = restTemplate.postForObject(url, requestBean, ResponseBean.class);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2、RestTemplate方法

    2.1 RestTemplate之Get请求

    RestTemplate有两个核心方法执行Get请求
    1)RestTemplate.getForObject()可以获取对象
    2)RestTemplate.getForEntity()可以获取对象,获取http状态码、请求头等

    springboot集成RestTemplate

    @Configuration
    public class RestConfig {
    
        @Bean
        public RestTemplate restTemplate(){
    
            // 默认底层执行HttpurlConnection
            return new RestTemplate();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    【RestTemplate.getForObject()样例程序】

     @Autowired
        private RestTemplate restTemplate;
    
        @GetMapping("/getForObject")
        public Object getForObject(){
            String url = "http://localhost:8080/addUser/100/mimimi";
            Map<String, Integer> map = new HashMap<>();
            UserDTO result = restTemplate.getForObject(url, UserDTO.class,map);
            return result;  //{"id":100,"name":"mimimi"}
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.2 restTemplate之Post请求

    Post请求包括两个核心方法:
    1)RestTemplate.postForObject()
    2)RestTemplate.postForEntity()
    Post方法方法传参Map必须是MutiValueMap;MutiValueMap支持基本类型分开传参,也支持实体传参

    一、postForObject

      // post请求:基本类型/实体传参
        @GetMapping("/postForObject")
        public UserDTO postForObject(){
            String url= "http://localhost:8080/addUser1";
            MultiValueMap<String,Object> map = new LinkedMultiValueMap<>();
    
            map.add("id",12);
            map.add("name","小黑");
            // 返回UserDTO对象
            UserDTO userDTO = restTemplate.postForObject(url,map, UserDTO.class);
            return userDTO; //{"id":12,"name":"小黑"}
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    二、postForEntity

     // post请求:postForEntity
        @GetMapping("/postForEntity1")
        public UserDTO postForEntity1(){
            String url="http://localhost:8080/addUser1";
    
            // 提交参数:使用 map 装载参数
            MultiValueMap<String,Object> map = new LinkedMultiValueMap<>();
            map.add("id",1000);
            map.add("name","hello restTemplate");
            //发送post请求
            ResponseEntity<UserDTO> userDTOResponseEntity= restTemplate.postForEntity(url,map, UserDTO.class);
    
            // postForEntity可以获取响应码、响应对象、响应头等
            HttpStatus status = userDTOResponseEntity.getStatusCode();
            int code = userDTOResponseEntity.getStatusCodeValue();
            HttpHeaders headers = userDTOResponseEntity.getHeaders();
            log.info("http响应码:{},响应状态码:{},headers信息:{}",status,code,headers);
            return userDTOResponseEntity.getBody();//{"id":1000,"name":"hello restTemplate"}
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    postForEntity()和getForObject()唯一的区别是:返回的时候使用ResponseEntity<>

    2.3 restTemplate.exchange()

    2.1 restTemplate.exchange()方法:
    在这里插入图片描述

    参数说明:url: 请求地址
    method:请求类型( POST 、GET等)
    requestEntity: 请求实体,封装请求头,请求内容
    responseType: 请求响应对象的类型
    uriVariables: url中的@PathVariable参数,可变长度参数列表

     // exchange
        @GetMapping("/exchange")
        public UserDTO exchange(){
            String url = "";
            // 传参使用MultiValueMap
            MultiValueMap<String,Object> map = new LinkedMultiValueMap<>();
            map.add("id",10);
            map.add("name","xixixi");
    
            // 请求使用HttpEntity,包装map
            HttpEntity<MultiValueMap> requestEntity = new HttpEntity<>(map);
            // 返回使用ResponseEntity
            ResponseEntity<UserDTO> response = restTemplate.exchange(url, HttpMethod.POST,requestEntity, UserDTO.class);
            return response.getBody();
        }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    restTemplate使用实践

    2.2 RestTemplate底层连接方式

    对于一个请求来说,超期时间,请求连接时间等都是必不可少的参数,为了更好的适应业务需求,所以可以自己修改restTemplate的配置
    restTemplate简书

            //生成一个设置了连接超时时间、请求超时时间、异常最大重试次数的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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    RestTemplate总结

  • 相关阅读:
    【Kubernetes | Pod 系列】Pod 的基本管理(1)——对 Pod 的创建
    java教材订购系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
    农村电力供应,这件事必须重视!
    【Azure 应用服务】App Service频繁出现 Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener 异常分析
    利用C++开发一个迷你的英文单词录入和测试小程序-升级版本
    ggplot 分面的细节调整汇总
    【校招VIP】产品职位理解之专业名词
    Ubuntu20.04上安装ssmtp通过SMTP方式发送邮件
    Android 13.0 Launcher3中去掉Hotseat功能实现
    【JavaSE】认识异常(下篇)
  • 原文地址:https://blog.csdn.net/Mikon_0703/article/details/132832849