使用RestTemplate方式发送HTTP请求详解

目录

一、RestTemplate方式发送HTTP请求代码示例

(1)发送Get请求

(2)发送Post请求

二、RestTemplate详解

1、RestTemplate简述

2、RestTemplate解析

HttpMessageConverter

创建RestTemplate

RestTemplate构造方法

3、RestTemplate API使用

GET方法

POST方法

exchange方法

三、RestTemplate扩展

1、设置拦截器(ClientHttpRequestInterceptor)

2、RestTemplate配置

1、处理请求头和响应头

2、ClientHttpRequestFactory

3、自定义messageConverter

使用fastjson做json转换

四、SpringBoot中使用RestTemplate


一、RestTemplate方式发送HTTP请求代码示例

RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。

使用apache的HttpClient开发,代码复杂,还得操心资源回收等。代码很复杂,冗余代码多,稍微截个图,这是一个封装好的get请求工具:

public static String get(String url, String paramsStr) {
        //创建一个默认的HttpClients对象
        CloseableHttpClient createDefault = HttpClients.createDefault();
        //创建一个get请求并发送参数
        HttpGet httpGet = new HttpGet(url + paramsStr);
        //设置http头部信息
        httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1;"
                + " Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0");
        httpGet.setHeader("Accept", "application/json");
        httpGet.setHeader("Accept-Encoding", "gzip, deflate");
        httpGet.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        //RequestConfig.Builder 配置器 ,我们可以通过custom获取一个新的Builder对象
        RequestConfig config = RequestConfig.custom()
                //设置链接超时的时间1秒钟
                .setConnectTimeout(90000)
                //设置读取超时1秒钟
                .setSocketTimeout(90000)
                //RequestConfig静态方法  setProxy  设置代理
                .build();
        //设置头部信息
        httpGet.setConfig(config);
        //实例话对象赋值
        CloseableHttpResponse execute = null;
        String jsonStr = "";
        try {
            //执行HttpClient
            execute = createDefault.execute(httpGet);
            //转化json格式 并防止乱码
            jsonStr = EntityUtils.toString(execute.getEntity(), "UTF-8");
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //关闭HttpClient
                createDefault.close();
                //关闭执行
                execute.close();
                //销毁GET请求
                httpGet.abort();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return jsonStr;
    }

下边贴下通过RestTemplate发送Http请求的代码:

(1)发送Get请求

代码示例:

/**
     * RestTemplate 发送  HTTP GET请求 --- 测试
     * @throws UnsupportedEncodingException
     */
    @Test
    public void doHttpGetTest() throws UnsupportedEncodingException {
        // -------------------------------> 获取Rest客户端实例
        RestTemplate restTemplate = new RestTemplate();

        // -------------------------------> 解决(响应数据可能)中文乱码 的问题
        List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
        converterList.remove(1); // 移除原来的转换器
        // 设置字符编码为utf-8
        HttpMessageConverter<?> converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
        converterList.add(1, converter); // 添加新的转换器(注:convert顺序错误会导致失败)
        restTemplate.setMessageConverters(converterList);

        // -------------------------------> (选择性设置)请求头信息
        // HttpHeaders实现了MultiValueMap接口
        HttpHeaders httpHeaders = new HttpHeaders();
        // 给请求header中添加一些数据
        httpHeaders.add("JustryDeng", "这是一个大帅哥!");

        // -------------------------------> 注:GET请求 创建HttpEntity时,请求体传入null即可
        // 请求体的类型任选即可;只要保证 请求体 的类型与HttpEntity类的泛型保持一致即可
        String httpBody = null;
        HttpEntity<String> httpEntity = new HttpEntity<String>(httpBody, httpHeaders);

        // -------------------------------> URI
        StringBuffer paramsURL = new StringBuffer("http://127.0.0.1:8080/http/doHttpTest");
        // 字符数据最好encoding一下;这样一来,某些特殊字符才能传过去(如:flag的参数值就是“&”,不encoding的话,传不过去)
        paramsURL.append("?flag=" + URLEncoder.encode("&&", "utf-8"));
        URI uri = URI.create(paramsURL.toString());

        //  -------------------------------> 执行请求并返回结果
        // 此处的泛型  对应 响应体数据   类型;即:这里指定响应体的数据装配为String
        ResponseEntity<String> response =
                restTemplate.exchange(uri, HttpMethod.GET, httpEntity, String.class);

        // -------------------------------> 响应信息
        //响应码,如:401、302、404、500、200等
        System.err.println(response.getStatusCodeValue());
        // 响应头
        System.err.println(JSON.toJSON(response.getHeaders()));
        // 响应体
        if(response.hasBody()) {
            System.err.println(response.getBody());
        }
    }

(2)发送Post请求

代码示例:

/**
     * RestTemplate 发送  HTTP POST请求 --- 测试
     * @throws UnsupportedEncodingException
     */
    @Test
    public void doHttpPostTest() throws UnsupportedEncodingException {
        // -------------------------------> 获取Rest客户端实例
        RestTemplate restTemplate = new RestTemplate();

        // -------------------------------> (选择性设置)请求头信息
        // HttpHeaders实现了MultiValueMap接口
        HttpHeaders httpHeaders = new HttpHeaders();
        // 设置contentType
        httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        // 给请求header中添加一些数据
        httpHeaders.add("JustryDeng", "这是一个大帅哥!");

        // ------------------------------->将请求头、请求体数据,放入HttpEntity中
        // 请求体的类型任选即可;只要保证 请求体 的类型与HttpEntity类的泛型保持一致即可
        // 这里手写了一个json串作为请求体 数据 (实际开发时,可使用fastjson、gson等工具将数据转化为json串)
        // String httpBody = "{\"motto\":\"唉呀妈呀!脑瓜疼!\"}";
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("name","是一个中文名");
        paramMap.put("englishName","merry");
        HttpEntity<Map<String,Object>> httpEntity = new HttpEntity<>(paramMap, httpHeaders);

        // -------------------------------> URI
        StringBuffer paramsURL = new StringBuffer("http://127.0.0.1:8080/http/doHttpTest");
        // 字符数据最好encoding一下;这样一来,某些特殊字符才能传过去(如:flag的参数值就是“&”,不encoding的话,传不过去)
        paramsURL.append("?flag=" + URLEncoder.encode("&&", "utf-8"));
        URI uri = URI.create(paramsURL.toString());

        //  -------------------------------> 执行请求并返回结果
        // 此处的泛型  对应 响应体数据   类型;即:这里指定响应体的数据装配为String
        // 访问方式一:
//        ResponseEntity<String> response =
//                restTemplate.exchange(uri, HttpMethod.POST, httpEntity, String.class);
        // 访问方式二:
        ResponseEntity<String> response = restTemplate.postForEntity(uri,httpEntity,String.class);

        // -------------------------------> 响应信息
        //响应码,如:401、302、404、500、200等
        System.err.println(response.getStatusCodeValue());
        // 响应头
        System.err.println(JSON.toJSON(response.getHeaders()));
        // 响应体
        if(response.hasBody()) {
            System.err.println(response.getBody());
        }

    }

对应的响应端代码:

@RequestMapping("/doHttpTest")
    public String doHttpGetTest(HttpServletRequest request, @RequestBody Map<String, Object> paramMap) throws IOException {
        System.out.println(request.getCharacterEncoding());
        // 不是请求体中的中文数据都需要转码
        String JustryDeng = new String(request.getHeader("JustryDeng").getBytes("ISO-8859-1"), "utf-8");
        System.out.println("获取Header传参:" + JustryDeng);
        // 获取URL上的参数
        String flag = request.getParameter("flag");
        System.out.println("获取URL传参:" + flag);
        // 接收对应的Body参数
        Map<String, Object> map = paramMap;
        return "访问成功!!!";
    }

注:HttpServletRequest 请求中的 body 内容仅能调用 request.getInputStream(), request.getReader()和request.getParameter("key") 方法读取一次,重复读取会报 java.io.IOException: Stream closed 异常。

request.getInputStream()只能读取一次,因此如果不对HttpServletRequest进行封装,在代码中直接通过流读取body中的内容就会抛出java.io.IOException: Stream closed 异常。

HttpEntity是请求体,可放置跟请求接口对应类型的数据。在示例中添加了许多格外的操作和代码注释,所以看起来比较臃肿,使用RestTemplate简洁的代码其实是这样的:

/**
     * RestTemplate 发送  HTTP POST请求 --- 测试
     * @throws UnsupportedEncodingException
     */
    @Test
    public void doHttpPostTest() throws UnsupportedEncodingException {
        // 1-------------------------------> 获取Rest客户端实例
        RestTemplate restTemplate = new RestTemplate();
        // 2-------------------------------> (选择性设置)请求头信息
        // HttpHeaders实现了MultiValueMap接口
        HttpHeaders httpHeaders = new HttpHeaders();
        // 3-------------------------------> 将请求头、请求体数据,放入HttpEntity中
        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put("name","是一个中文名");
        HttpEntity<Map<String,Object>> httpEntity = new HttpEntity<>(paramMap, httpHeaders);
        // 4-------------------------------> 执行请求并返回结果
        ResponseEntity<String> response = restTemplate.postForEntity(
                "http://127.0.0.1:8080/http/doHttpTest",httpEntity,String.class);
        // 5-------------------------------> 响应信息
        if(response.hasBody()) {
            System.err.println(response.getBody());
        }
    }

当然你还可以去除注释和进行简单封装,发现它其实就几行代码,对于Get请求来说,就更加简单了,这个没什么好写的。

二、RestTemplate详解

1、RestTemplate简述

RestTemplate是Spring的通过客户端访问RESTful服务端的核心类,和JdbcTemplate、JmsTemplate概念相似,都是Spring提供的模板类。

RestTemplate的行为可以通过callback回调方法和配置HttpMessageConverter来定制,用来把对象封装到HTTP请求体,将响应信息放到一个对象中。

RestTemplate能大幅简化提交表单数据的难度,并且附带了自动转换JSON数据的功能,但只有理解了HttpEntity的组成结构(header与body),且理解了与uriVariables之间的差异,才能真正掌握其用法。这一点在Post请求更加突出。

2、RestTemplate解析

HttpMessageConverter

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swadian2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值