Java Http请求方式之RestTemplate常用方法详解

目录
  • 引言
  • 常见用法
    • 简单Get\Post请求
    • Post提交常规表单
    • Post上传文件
  • 配置项
    • 请求添加Cookie\Header
    • 配置请求工厂 超时、代理
    • 配置拦截器、转换器,错误处理
    • 错误重试(额外)
    • SSL请求
  • 基于RestTemplate一些工具
    • 钉钉机器人通知
  • 总结

引言

在开发中有时候经常需要一些Http请求,请求数据,下载内容,也有一些简单的分布式应用直接使用Http请求作为跨应用的交互协议。

在Java中有不同的Http请求方式,主要就是HttpURLConnection或者ApacheHttpClient,但是这两个用起来都感觉有那么一点点的复杂;

好在Spring内置了RestTemplate作为Http请求的工具类,简化了很多操作,虽然Spring5推出了WebClient,但是整体感觉还是RestTemplate用起来更简单方便一些。

这里记录分享下RestTemplate的常见使用方式,RestTemplate作为Java中最简单好用的Http请求工具类一定要了解一下

常见用法

简单Get\Post请求

    @Test
    public void testGetPost(){
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().add(new FastJsonHttpMessageConverter());
        String res = restTemplate.postForObject("http://test.aihe.space/", null, String.class);
        System.out.println(res);
        String res2 = restTemplate.getForObject("http://test.aihe.space/",  String.class);
        System.out.println(res2);
    }

Post提交常规表单

    @Test
    public void testPostFrom(){
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
        map.add("id", "1");
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
        String fooResourceUrl = "http://test.aihe.space/";
        ResponseEntity<String> response = restTemplate.postForEntity(fooResourceUrl, request, String.class);
        System.out.println(response.getStatusCode());
        System.out.println(response.getBody());
    }

Post上传文件

注意:上传文件时的value为FileSystemResource

@Test
    public void testPostFile(){
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        MultiValueMap<String, Object> map= new LinkedMultiValueMap<>();
        map.add("id", "1");
        map.add("file",new FileSystemResource("/Users/aihe/code/init/src/test/java/me/aihe/RestTemplateTest.java"));
        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers);
        String fooResourceUrl = "http://test.aihe.space/";
        ResponseEntity<String> response = restTemplate.postForEntity(fooResourceUrl, request, String.class);
        System.out.println(response.getStatusCode());
        System.out.println(response.getBody());
    }

配置项

请求添加Cookie\Header

@Test
    public void testCookieHeader(){
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        MultiValueMap<String, Object> map= new LinkedMultiValueMap<>();
        // 常见的Header都可以直接设置
//        headers.set
        headers.set("custom1","customValue1");
        // 设置Cookie
        headers.set(HttpHeaders.COOKIE,"xxxx");
        map.add("id", "1");
        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(map, headers);
        String fooResourceUrl = "http://test.aihe.space/";
        ResponseEntity<String> response = restTemplate.postForEntity(fooResourceUrl, request, String.class);
        System.out.println(response.getStatusCode());
        System.out.println(response.getBody());
    }

配置请求工厂 超时、代理

使用Rest请求的时候注意设置超时时间

@Test
    public void testHttpFactory(){
        RestTemplate restTemplate = new RestTemplate();
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setReadTimeout(5000);
        requestFactory.setConnectTimeout(3000);
        Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 7890));
        requestFactory.setProxy(proxy);
        restTemplate.setRequestFactory(requestFactory);
        restTemplate.getMessageConverters().add(new FastJsonHttpMessageConverter());
        String res = restTemplate.postForObject("http://test.aihe.space/", null, String.class);
        System.out.println(res);
    }

配置拦截器、转换器,错误处理

@Test
    public void testConverterInterceptor(){
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setInterceptors(Collections.singletonList(new BasicAuthenticationInterceptor("admin","admin")));
        restTemplate.getMessageConverters().add(new FastJsonHttpMessageConverter());
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
        String res = restTemplate.postForObject("http://test.aihe.space/", null, String.class);
        System.out.println(res);
    }

错误重试(额外)

可以考虑使用Spring Retry,但是相当于引入了新的东西,如果没有特殊必要,可以自己简单用for循环做下;

SSL请求

参考:stackoverflow.com/questions/1…

@Test
    public void testSSL() throws FileNotFoundException, NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
        String keyStorePassword = "123456";
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(new FileInputStream(new File("keyStoreFile")),
                keyStorePassword.toCharArray());
        SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
                new SSLContextBuilder()
                        .loadTrustMaterial(null, new TrustSelfSignedStrategy())
                        .loadKeyMaterial(keyStore, keyStorePassword.toCharArray())
                        .build(),
                NoopHostnameVerifier.INSTANCE);
        HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(
                socketFactory).build();
        ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(
                httpClient);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        String res = restTemplate.postForObject("http://test.aihe.space/", null, String.class);
        System.out.println(res);
    }

基于RestTemplate一些工具

钉钉机器人通知

可以支持发送普通文本、ActionCard,Markdown的消息

import java.util.ArrayList;
import java.util.List;
import lombok.Data;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
/**
 * 使用场景:
 * 功能描述:https://developers.dingtalk.com/document/app/custom-robot-access/title-72m-8ag-pqw
 */
@Slf4j
public class RobotUtils {
    private static RestTemplate restTemplate = new RestTemplate();
    private static String URL = "";
    public static void main(String[] args) {
        sendMarkDownMsg(
            URL,
            "测试",
            "测试",
            new ArrayList<>()
        );
    }
    /**
     * {
     * "msgtype": "text",
     * "text": {
     * "content": "我就是我, @150XXXXXXXX 是不一样的烟火"
     * },
     * "at": {
     * "atMobiles": [
     * "150XXXXXXXX"
     * ],
     * "isAtAll": false
     * }
     * }
     */
    public static void sendTextMsg(String url, String content, List<String> atPerson) {
        RobotMsg robotMsg = new RobotMsg();
        robotMsg.setMsgtype("text");
        RobotAt robotAt = new RobotAt();
        robotAt.setAtAll(false);
        if (atPerson != null && atPerson.size() > 0) {
            robotAt.setAtMobiles(atPerson);
        }
        robotMsg.setAt(robotAt);
        RobotText robotText = new RobotText();
        robotText.setContent(content);
        robotMsg.setText(robotText);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, robotMsg, String.class);
        log.info("sendTextMsg {}",responseEntity.getBody());
    }
    /**
     * @param url            机器人地址
     * @param title          actionCard标题
     * @param text           缩略内容
     * @param vertical 按钮方向
     * @param btns           按钮内容
     */
    public static void sendActionCardMsg(String url, String title, String text, Boolean vertical, List<RobotBtn> btns) {
        RobotMsg robotMsg = new RobotMsg();
        robotMsg.setMsgtype("actionCard");
        RobotAt robotAt = new RobotAt();
        robotAt.setAtAll(false);
        RobotActionCard robotActionCard
            = new RobotActionCard();
        robotActionCard.setTitle(title);
        robotActionCard.setText(text);
        robotActionCard.setBtnOrientation((vertical == null || vertical) ? "0" : "1");
        robotActionCard.setBtns(btns);
        robotMsg.setActionCard(robotActionCard);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, robotMsg, String.class);
        System.out.println(responseEntity.getBody());
    }
    public static void sendMarkDownMsg(String url,String title,String text,List<String> atPerson){
        RobotMarkDownMsg markDownMsg = new RobotMarkDownMsg();
        markDownMsg.setMsgtype("markdown");
        RobotAt robotAt = new RobotAt();
        robotAt.setAtAll(false);
        if (atPerson != null && atPerson.size() > 0) {
            robotAt.setAtMobiles(atPerson);
        }
        markDownMsg.setAt(robotAt);
        RobotMarkdownText markdownText = new RobotMarkdownText();
        markdownText.setTitle(title);
        markdownText.setText(text);
        markDownMsg.setMarkdown(markdownText);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, markDownMsg, String.class);
        System.out.println(responseEntity.getBody());
    }
    public enum SupportRobotEnum {
        /**
         * 测试机器人群
         */
        CESHI("测试机器人群",
            "");
        @Getter
        private String desc;
        @Getter
        private String url;
        SupportRobotEnum(String desc, String url) {
            this.desc = desc;
            this.url = url;
        }
    }
    @Data
    public static class RobotAt {
        public List<String> atMobiles;
        public boolean isAtAll;
    }
    @Data
    public static class RobotMarkDownMsg{
        public String msgtype;
        public RobotAt at;
        public RobotMarkdownText markdown;
    }
    @Data
    public static class RobotMarkdownText {
        String title;
        String text;
    }
    @Data
    public static class RobotMsg {
        public String msgtype;
        public RobotAt at;
        /**
         * 普通文字消息类型消息
         */
        public RobotText text;
        /**
         * actionCard类型消息时支持
         */
        public RobotActionCard actionCard;
    }
    @Data
    public static class RobotText {
        public String content;
    }
    @Data
    public static class RobotActionCard {
        public String title;
        public String text;
        public String hideAvatar;
        public String btnOrientation;
        public List<RobotBtn> btns;
    }
    @Data
    public static class RobotBtn {
        public String title;
        public String actionURL;
        public static RobotBtn buildBtn(String title, String actionUrl) {
            RobotBtn robotBtn = new RobotBtn();
            robotBtn.setActionURL(actionUrl);
            robotBtn.setTitle(title);
            return robotBtn;
        }
    }
}

总结

1、 Http请求在开发过程中也是一个常见的高频操作;

2、Spring封装了Http的工具类RestTemplate非常好用,基本上满足了所有Http相关的需求。

3、这里介绍整理了下RestTemplate的常见使用方式,遇到有对应的内容,直接翻阅使用即可。

以上就是Java Http请求方式之RestTemplate常用方法详解的详细内容,更多关于Java Http请求方式RestTemplate的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java HttpClient技术详解

    目录 一.HttpClient 1.1. 前台系统访问后台接口的方式 1.2. 什么是HttpClient 1.3. HttpClient入门案例 1.3.1. 发起Get请求 1.3.2. 带参数的Get请求 1.3.3. 发起POST请求 1.3.4. 带参数POST请求 二.项目整合HttpClient-与SpringBoot整合 1.导入maven坐标 2.在项目中创建HttpClientConfig类–类似util 3.在application.properties添加如下配置: 4.

  • Java如何实现通过证书访问Https请求

    目录 Java通过证书访问Https请求 创建证书管理器类 调用测试 工具类 https请求绕过证书检测 Java通过证书访问Https请求 创建证书管理器类 import java.io.FileInputStream; import java.security.KeyStore; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net

  • Java Http多次请求复用同一连接示例详解

    目录 概述 复用的基本条件 理论基础 现实基础 获取HTTP资源常见方式 Transfer-Encoding 简略实现 概述 注: 本文乃是最简单的实现,真实场景要复杂麻烦的多 旨在阐述清晰多次HTTP请求复用一个连接的底层逻辑 早在HTTP/1.0时代,每次HTTP请求都要创建一个连接,而创建连接的过程需要消耗资源和时间,代价相对昂贵,为了减少资源消耗,缩短响应时间,就需要重用连接.在后来的HTTP/1.1中,引入了连接复用的机制,Http Header中加入Connection: keep-

  • Java9新特性对HTTP2协议支持与非阻塞HTTP API

    目录 一.HTTP/2简介 HTTP/2数据推送 目前支持HTTP/2的JavaHTTP客户端 二.Java9的HTTP/2客户端 在阻塞模式下发送请求 以非阻塞模式发送请求(Java9) 三.支持HTTP2的Push-PromiseFrames 在HTTP/1.1 发布了16 年之后,IETF在2015年终于通过了HTTP/2 协议.HTTP/2协议旨在降低延迟,满足当今时代对于信息响应时间的要求.在这篇文章中,我会简要的对HTTP/2协议进行介绍,然后我们将重点放在研究Java9中对HTTP

  • Java调用第三方http接口的常用方式总结

    目录 1.概述 在Java项目中调用第三方接口的常用方式有 2.Java调用第三方http接口的方式 2.1 通过JDK网络类Java.net.HttpURLConnection 2.2 通过apache common封装好的HttpClient 2.3 通过Apache封装好的CloseableHttpClient 2.4 通过OkHttp 2.5 通过Spring的RestTemplate 2.6通过hutool的HttpUtil 3.总结 1.概述 在实际开发过程中,我们经常需要调用对方提

  • Java使用GZIP压缩导致HTTP请求返回乱码问题解决

    目录 原因 思路 解决方法 代码 关键部分 完整代码 原因 用Java调用雪球的API,结果返回的是乱码,一番研究后发现是因为返回的数据使用了GZIP压缩,需要先解压才能得到正确数据. 思路 使用了GZIP压缩的数据在响应头里会有一项名为content-encoding的参数,值为gzip. Java中可以使用.getHeaderField()读取响应头的参数. 如果没有这项参数,会返回null. 解决方法 用.getHeaderField("content-encoding")读取c

  • Java Http请求方式之RestTemplate常用方法详解

    目录 引言 常见用法 简单Get\Post请求 Post提交常规表单 Post上传文件 配置项 请求添加Cookie\Header 配置请求工厂 超时.代理 配置拦截器.转换器,错误处理 错误重试(额外) SSL请求 基于RestTemplate一些工具 钉钉机器人通知 总结 引言 在开发中有时候经常需要一些Http请求,请求数据,下载内容,也有一些简单的分布式应用直接使用Http请求作为跨应用的交互协议. 在Java中有不同的Http请求方式,主要就是HttpURLConnection或者Ap

  • Java struts2请求源码分析案例详解

    Struts2是Struts社区和WebWork社区的共同成果,我们甚至可以说,Struts2是WebWork的升级版,他采用的正是WebWork的核心,所以,Struts2并不是一个不成熟的产品,相反,构建在WebWork基础之上的Struts2是一个运行稳定.性能优异.设计成熟的WEB框架. 我这里的struts2源码是从官网下载的一个最新的struts-2.3.15.1-src.zip,将其解压即可.里面的目录页文件非常的多,我们只需要定位到struts-2.3.15.1\src\core

  • Java Map接口概述和常用方法详解

    目录 概述 Map常用子类 Map接口中的常用方法 Map集合遍历键找值方式 Entry键值对对象 Map集合遍历键值对方式 概述 现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射.Java提供了专门的集合类用来存放这种对象关系的对象,即java.util.Map接口. 我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同,如下图. Collection中的

  • Java中map遍历方式的选择问题详解

    1. 阐述 对于Java中Map的遍历方式,很多文章都推荐使用entrySet,认为其比keySet的效率高很多.理由是:entrySet方法一次拿到所有key和value的集合:而keySet拿到的只是key的集合,针对每个key,都要去Map中额外查找一次value,从而降低了总体效率.那么实际情况如何呢? 为了解遍历性能的真实差距,包括在遍历key+value.遍历key.遍历value等不同场景下的差异,我试着进行了一些对比测试. 2. 对比测试 一开始只进行了简单的测试,但结果却表明k

  • 浅谈Java HttpURLConnection请求方式

    一)URL代理请求 ​ 该方式请求有两种代理方式. 方式一:使用该方式代理之后,之后的所有接口都会使用代理请求 // 对http开启全局代理 System.setProperty("http.proxyHost", "192.168.1.1"); System.setProperty("http.proxyPort", "80"); // 对https开启全局代理 System.setProperty("https.

  • java数组的三种扩容方式以及程序实现详解

    因为数组是在内存中连续的一段存储空间,所以数组一旦被创建,空间就固定了,长度是不能扩增的. 数组的长度是固定的,如果需要扩充**,必须创建新数组,原数组的长度要复制到新数组中 .** java中,数组类型的变量传值的时候,事实上传递的是数组的地址 . Java数组扩容的原理 1)Java数组对象的大小是固定不变的,数组对象是不可扩容的. 2)利用数组复制方法可以变通的实现数组扩容. 3)System.arraycopy()可以复制数组. 4)Arrays.copyOf()可以简便的创建数组副本.

  • Java连接MongoDB的常用方法详解

    目录 一.Java链接MongoDB 二.查看库,查看集合 三.Java对MongoDB增删改查 1. 添加数据 2. 删除数据 3. 修改数据 4. 查询数据 一.Java链接MongoDB 1. 导入Mongo驱动包 2. 获取Mongo链接对象 MongoClient mc = new MongoClient("localhost",27017); 3. 关闭链接 mc.close(); 二.查看库,查看集合 1. 获取库对象 MongoDatabase db = mc.getD

  • java中Executor,ExecutorService,ThreadPoolExecutor详解

    java中Executor,ExecutorService,ThreadPoolExecutor详解 1.Excutor 源码非常简单,只有一个execute(Runnable command)回调接口 public interface Executor { /** * Executes the given command at some time in the future. The command * may execute in a new thread, in a pooled thre

  • java 中HttpClient传输xml字符串实例详解

    java 中HttpClient传输xml字符串实例详解 介绍:我现在有一个对象page,需要将page对象转换为xml格式并以binary方式传输到服务端 其中涉及到的技术点有: 1.对象转xml流 2.输出流转输入流 3.httpClient发送二进制流数据 POM文件依赖配置 <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifact

  • java 中JDBC连接数据库代码和步骤详解及实例代码

    java 中JDBC连接数据库代码和步骤详解 JDBC连接数据库 •创建一个以JDBC连接数据库的程序,包含7个步骤:  1.加载JDBC驱动程序:  在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机),这通过java.lang.Class类的静态方法forName(String  className)实现. 例如: try{ //加载MySql的驱动类 Class.forName("com.mysql.jdbc.Driver") ; }catch(Class

随机推荐