SpringBoot使用RestTemplate实现发送HTTP请求

news2024/10/19 18:43:03

 Java 实现发送 HTTP 请求,系列文章:

《Java使用原生HttpURLConnection实现发送HTTP请求》

《Java使用HttpClient5实现发送HTTP请求》

《SpringBoot使用RestTemplate实现发送HTTP请求》

1、RestTemplate 的介绍

RestTemplate 是 Spring 框架提供的一个用于访问 RESTful 服务的客户端工具,它简化了与 RESTful 服务的交互,并提供了一系列方便的方法来发送 HTTP 请求、处理响应以及处理错误。

RestTemplate 的主要特点:

  1. 简化的API:RestTemplate 提供了一组简单易用的方法,使得发送HTTP请求变得非常简单和直观。
  2. 支持多种HTTP方法:RestTemplate 支持 GET、POST、PUT、DELETE 等多种 HTTP 方法,可以满足不同的业务需求。
  3. 内置的序列化和反序列化支持:RestTemplate 可以自动将请求和响应的 JSON/XML 数据转换为 Java 对象,简化了数据的处理过程。
  4. 异常处理:RestTemplate 提供了对 HTTP 请求过程中可能出现的异常进行处理的机制,方便开发者进行错误处理和容错机制的实现。
  5. 可扩展性:RestTemplate 可以通过自定义的 HttpMessageConverter 来支持更多的数据格式和序列化方式。
  6. Spring生态的无缝集成:RestTemplate 是 Spring 框架的一部分,可以与其他 Spring 组件(如Spring MVC)无缝集成,提供更加便捷的开发体验。

RestTemplate 的常用方法:

类型方法说明
GET 请求getForObject发送 GET 请求,并返回响应体转换成的对象。
getForEntity发送 GET 请求,并返回包含响应详细信息(如响应码、响应头等)的 ResponseEntity 对象。
POST 请求postForObject发送 POS T请求,并返回响应体转换成的对象。
postForEntity发送 POST 请求,并返回包含响应详细信息的 ResponseEntity 对象。
exchange发送一个通用的请求,并返回 ResponseEntity 对象。这个方法非常灵活,可以发送 GET、POST、PUT、DELETE 等多种类型的请求。
其它请求put发送 PUT 请求。
delete发送 DELETE 请求。
optionsForAllow发送 OPTIONS 请求,并返回服务器允许的 HTTP 方法。
headForHeaders发送 HEAD 请求,并返回响应头信息。

2、创建 RestTemplate 工具类

通过将常用的方法封装到工具类中,可以避免重复编写相同的代码,从而提高代码的复用性‌。

(1)添加 Maven 依赖

在项目的 pom.xml 配置文件中添加 RestTemplate 依赖。

创建 Spring Boot 项目后,一般都会引用 spring-boot-starter-web 依赖,在该依赖中已经包含  RestTemplate 的依赖。

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

(2)创建配置类

 在 config 目录下,创建 RestTemplateConfig 类(RestTemplate配置类)。

package com.pjb.consumer.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
 * RestTemplate配置类
 * @author pan_junbiao
 **/
@Configuration
public class RestTemplateConfig
{
    // 超时时间
    private final static int timeOut = 60000; //60秒

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory factory)
    {
        RestTemplate restTemplate = new RestTemplate(factory);
        return restTemplate;
    }

    /**
     * 自定义请求工厂
     */
    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory()
    {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(timeOut);     // 设置读取超时时间
        factory.setConnectTimeout(timeOut);  // 设置连接超时时间
        return factory;
    }
}

(3)创建工具类

 在 util 目录下,创建 HttpRestTemplateUtil 类(基于 RestTemplate 的 HTTP 请求工具类)。

package com.pjb.consumer.util;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.net.URI;
import java.util.Map;

/**
 * 基于 RestTemplate 的 HTTP 请求工具类
 * @author pan_junbiao
 **/
@Component
public class HttpRestTemplateUtil
{
    @Resource
    private RestTemplate restTemplate;

    /**
     * 发送 GET 请求并获取响应数据
     *
     * @param url    请求地址
     * @param params 请求参数
     * @return 响应数据字符串
     */
    public String doGet(String url, Map<String, String> params)
    {
        try
        {
            // 1、拼接 URL
            StringBuffer stringBuffer = new StringBuffer(url);
            if (params != null && !params.isEmpty())
            {
                stringBuffer.append("?");
                for (Map.Entry<String, String> entry : params.entrySet())
                {
                    stringBuffer.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
                }
                stringBuffer.deleteCharAt(stringBuffer.length() - 1);
            }
            URI targetUri = new URI(stringBuffer.toString());

            // 2、执行请求操作,并返回响应结果
            String result = restTemplate.getForObject(targetUri, String.class);
            return result;
        } catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 发送 POST 请求并获取响应数据
     *
     * @param url    请求地址
     * @param params 请求参数
     * @return 响应数据字符串
     */
    public String doPost(String url, Map<String, String> params)
    {
        try
        {
            //1、设置请求参数
            LinkedMultiValueMap<String, String> valueMap = new LinkedMultiValueMap<>();
            if (params != null && !params.isEmpty())
            {
                for (Map.Entry<String, String> entry : params.entrySet())
                {
                    valueMap.set(entry.getKey(), entry.getValue());
                }
            }

            // 2、执行请求操作,并返回响应结果
            String result = restTemplate.postForObject(url, valueMap, String.class);
            return result;
        } catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 发送 JSON 格式的 POST 请求并获取响应数据
     *
     * @param url       请求地址
     * @param jsonParam JSON格式的请求参数
     * @return 响应数据字符串
     */
    public String doJsonPost(String url, String jsonParam)
    {
        try
        {
            // 1、设置请求头
            HttpHeaders headers = new HttpHeaders();
            MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
            headers.setContentType(type);
            headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            HttpEntity<String> formEntity = new HttpEntity<String>(jsonParam, headers);

            // 2、执行请求操作,并返回响应结果
            String result = restTemplate.postForObject(url, formEntity, String.class);
            return result;
        } catch (Exception ex)
        {
            ex.printStackTrace();
        }
        return null;
    }
}

3、综合实例

【实例】实现用户信息的查询、新增、修改、删除接口,并使用 HttpClient5 实现接口的请求。

(1)在 controller 层,创建用户信息控制器类,实现查询、新增、修改、删除接口。

package com.pjb.business.controller;

import com.pjb.business.entity.UserInfo;
import com.pjb.business.exception.ApiResponseException;
import com.pjb.business.model.ApiModel.ApiResponseCode;
import com.pjb.business.model.ApiModel.ApiResponseResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * 用户信息控制器类
 * @author pan_junbiao
 **/
@RestController
@RequestMapping("/user")
@Api(description = "用户信息控制器")
public class UserController
{
    /**
     * 查询用户信息
     */
    @ApiOperation(value = "查询用户信息")
    @RequestMapping(value = "/getUserInfo", method = RequestMethod.GET)
    public ApiResponseResult<UserInfo> getUserInfo(Long userId)
    {
        if (userId <= 0)
        {
            //使用:全局异常处理
            throw new ApiResponseException(ApiResponseCode.PARAMETER_ERROR);
        }

        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userId);
        userInfo.setUserName("pan_junbiao的博客");
        userInfo.setBlogName("您好,欢迎访问 pan_junbiao的博客");
        userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");

        //使用:统一返回值
        return new ApiResponseResult(ApiResponseCode.SUCCESS, userInfo);
    }

    /**
     * 新增用户信息
     */
    @ApiOperation(value = "新增用户信息")
    @RequestMapping(value = "/addUserInfo", method = RequestMethod.POST)
    public ApiResponseResult<Boolean> addUserInfo(@RequestBody UserInfo userInfo)
    {
        if (userInfo == null || userInfo.getUserName() == null || userInfo.getUserName().length() == 0)
        {
            //使用:全局异常处理
            throw new ApiResponseException(ApiResponseCode.PARAMETER_ERROR);
        }

        //使用:统一返回值
        return new ApiResponseResult(ApiResponseCode.SUCCESS, true);
    }

    /**
     * 修改用户信息
     */
    @ApiOperation(value = "修改用户信息")
    @RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST)
    public ApiResponseResult<Boolean> updateUserInfo(@RequestBody UserInfo userInfo)
    {
        if (userInfo == null && userInfo.getUserId() <= 0)
        {
            //使用:全局异常处理
            throw new ApiResponseException(ApiResponseCode.PARAMETER_ERROR);
        }

        //使用:统一返回值
        return new ApiResponseResult(ApiResponseCode.SUCCESS, true);
    }

    /**
     * 删除用户信息
     */
    @ApiOperation(value = "删除用户信息")
    @RequestMapping(value = "/deleteUserInfo", method = RequestMethod.POST)
    public ApiResponseResult<Boolean> deleteUserInfo(Long userId)
    {
        if (userId <= 0)
        {
            //使用:全局异常处理
            throw new ApiResponseException(ApiResponseCode.PARAMETER_ERROR);
        }

        //使用:统一返回值
        return new ApiResponseResult(ApiResponseCode.SUCCESS, true);
    }
}

(2)使用 RestTemplate 发送 Get 请求,查询用户信息。

@Resource
private HttpRestTemplateUtil httpRestTemplateUtil;

/**
 * 使用 RestTemplate 发送 Get 请求,查询用户信息
 */
@Test
public void getUserInfo()
{
    //请求地址
    String url = "http://localhost:8085/user/getUserInfo";

    //请求参数
    Map<String, String> params = new HashMap<>();
    params.put("userId", "1");

    //发送 HTTP 的 Get 请求(核心代码)
    String httpResult = httpRestTemplateUtil.doGet(url, params);

    //反序列化JSON结果
    ApiResponseResult<UserInfo> responseResult = JacksonUtil.getJsonToGenericityBean(httpResult, ApiResponseResult.class, UserInfo.class);
    UserInfo userInfo = responseResult.getData();
    System.out.println("响应JSON结果:" + httpResult);
    System.out.println("响应结果编码:" + responseResult.getCode());
    System.out.println("响应结果信息:" + responseResult.getMessage());
    System.out.println("用户编号:" + userInfo.getUserId());
    System.out.println("用户名称:" + userInfo.getUserName());
    System.out.println("博客信息:" + userInfo.getBlogName());
    System.out.println("博客地址:" + userInfo.getBlogUrl());
}

执行结果:

(3)使用 RestTemplate 发送 POST 请求,删除用户信息。

@Resource
private HttpRestTemplateUtil httpRestTemplateUtil;

/**
 * 使用 RestTemplate 发送 POST 请求,删除用户信息
 */
@Test
public void deleteUserInfo()
{
    //请求地址
    String url = "http://localhost:8085/user/deleteUserInfo";

    //请求参数
    Map<String, String> params = new HashMap<>();
    params.put("userId","3");

    //发送 HTTP 的 POST 请求(核心代码)
    String httpResult = httpRestTemplateUtil.doPost(url, params);
    System.out.println("响应结果:" + httpResult);
}

执行结果:

响应结果:{"code":200000,"message":"操作成功","data":true}

(4)使用 RestTemplate 发送 JSON 格式的 POST 请求,新增用户信息。

@Resource
private HttpRestTemplateUtil httpRestTemplateUtil;

/**
 * 使用 RestTemplate 发送 JSON 格式的 POST 请求,新增用户信息
 */
@Test
public void addUserInfo()
{
    //请求地址
    String url = "http://localhost:8085/user/addUserInfo";

    //请求参数
    UserInfo userInfo = new UserInfo();
    userInfo.setUserId(2L);
    userInfo.setUserName("pan_junbiao的博客");
    userInfo.setBlogName("您好,欢迎访问 pan_junbiao的博客");
    userInfo.setBlogUrl("https://blog.csdn.net/pan_junbiao");
    String json = JacksonUtil.getBeanToJson(userInfo);

    //发送 JSON 格式的 POST 请求(核心代码)
    String httpResult = httpRestTemplateUtil.doJsonPost(url, json);
    System.out.println("响应结果:" + httpResult);
}

执行结果:

响应结果:{"code":200000,"message":"操作成功","data":true}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2218674.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前端】如何制作一个自己的网页(9)

前面&#xff0c;我们使用的CSS选择器&#xff0c;是通过元素的标签来指定网页的样式。而CSS中提供了多种不同类型的选择器&#xff0c;我们需要根据不同的情况&#xff0c;选择不同的CSS选择器。 CSS中&#xff0c;常见的基础选择器有三种。分别为&#xff1a;标签选择器、类选…

案例分享—国外优秀UI卡片设计作品赏析

国外UI设计注重用户体验&#xff0c;倾向于采用简洁的布局、清晰的排版和直观的交互方式&#xff0c;减少用户的认知负担。卡片式设计能够完美利用屏幕空间&#xff0c;使内容一目了然&#xff0c;易于用户快速浏览和阅读&#xff0c;从而提升了整体的用户体验。 更加注重扁平化…

一款.NET开源的i茅台自动预约小助手

前言 今天大姚给大家分享一款.NET开源、基于WPF实现的i茅台APP接口自动化每日自动预约&#xff08;抢茅台&#xff09;小助手&#xff1a;HyggeImaotai。 项目介绍 该项目通过接口自动化模拟i茅台APP实现每日自动预约茅台酒的功能&#xff0c;软件会在指定时间开始对管理的用…

数据结构与算法 - 树 #数的概念 #二叉树 #堆 - 堆的实现/堆排序/TOP-K问题

文章目录 前言 一、树 (一)、概念 1、树的定义 (二)、树的定义 1、树为什么是递归定义的&#xff1f; 2、如何定义树(如何表达一棵树) 解决方案一&#xff1a;假设我们得知该树的度 解决方案二&#xff1a;顺序表 解决方案三&#xff1a;左孩子右兄弟表示法 二、二叉…

众数信科荣登“2024 CHINA AIGC 100”榜单

2024年10月17日&#xff0c;由非凡产研推出的「2024 CHINA AIGC 100」榜单隆重发布&#xff0c;众数信科凭借领先的企业AI智能体解决方案能力荣登榜单。 非凡产研AIGC 100 评选旨在挖掘国内具有高潜力的AI应用&#xff0c;为AI产业的高质量发展注入新动力。榜单覆盖了教育、医疗…

无人机之融合集群技术篇

无人机的融合集群技术是一个涉及多个领域的复杂技术体系&#xff0c;它结合了无人机技术、自组网技术、集群控制技术以及反制设备等多个方面&#xff0c;旨在实现多架无人机之间的协同、编队、信息共享、任务分配和高效作业。 一、无人机自组网技术 无人机自组网技术是一种利用…

vulnhub靶场之digitalworld.local DEVELOPMENT

一.环境搭建 1.靶场描述 This machine reminds us of a DEVELOPMENT environment: misconfigurations rule the roost. This is designed for OSCP practice, and the original version of the machine was used for a CTF. It is now revived, and made slightly more nefari…

Linux 之 fdisk 【磁盘分区管理】

删除分区 1.查看磁盘信息 lsblk 2.删除分区sdb硬盘下的所有分区 # 1 进入d的磁盘分区 fdisk /dev/sdb # 2 输入p查看磁盘的分区信息 # 3 输入d进入删除磁盘分区命令 # 4 选择要删除的分区号 重复3&#xff0c;4 全部删除 # 5 w 保存退出并生效操作信息 &#xff08;输入q…

面试应该问什么?

在求职者面试的过程中&#xff0c;向面试官提问是一个展现自己积极态度、对职位和公司兴趣以及进一步了解工作环境和职业发展机会的重要环节。以下是一些求职者可以在面试中向面试官提问的问题&#xff0c;这些问题旨在帮助你更全面地了解未来的工作环境、团队文化、以及个人职…

联系拯救者Y9000P2022笔记本电脑进入BIOS快捷键

联系拯救者Y9000P2022笔记本电脑进入BIOS快捷键 文章目录 联系拯救者Y9000P2022笔记本电脑进入BIOS快捷键1. 进入BIOS快捷键2. 快速进入BIOS设置界面3. 快速进入启动项选择界面 1. 进入BIOS快捷键 进入BIOS设置界面的快捷键为F2快速进入启动项选择界面的快捷键为F12 2. 快速进…

82.【C语言】数据结构之顺序表的初始化和销毁

目录 1.线性表 2.分类 1.静态顺序表&#xff1a;使用定长数组存储元素 代码示例(写入Seqlist.h中) 2.动态顺序表:使用与动态内存管理有关的函数 代码示例(写入Seqlist.h中) 补:数据管理的四个需求:增改删查 3.操作顺序表 1.初始化顺序表 1.不开辟空间 2.开辟空间 1…

音乐播放器-0.专栏介绍​

1.简介 本专栏使用Qt QWidget作为显示界面&#xff0c;你将会学习到以下内容&#xff1a; 1.大量ui美化的实例。 2.各种复杂ui布局。 3.常见显示效果实现。 4.大量QSS实例。 5.Qt音频播放&#xff0c;音乐歌词文件加载&#xff0c;展示。 6.播放器界面换肤。 相信学习了本专栏…

Vxe UI vue vxe-table grid 性能优化,提高渲染性能

Vxe UI vue vxe-table vxe-grid 本身就支持虚拟滚动以及灵活的扩展&#xff0c;可也是由于太过灵活&#xff0c;可定制化程度太高&#xff0c;比如单元格自定义渲染&#xff0c;一旦写得不好&#xff0c;就会影响渲染卡顿。 vxe-table 和 vxe-grid 直接使用 vxe-grid&#xf…

AI论文写作:如何轻松实现高原创度大揭秘

随着人工智能技术的迅猛进步&#xff0c;AI论文写作工具在学术界开始崭露头角&#xff0c;作为一种辅助手段。这些工具不仅能高效地生成论文的初步版本或部分章节&#xff0c;而且其产出的内容往往展现出高度的创新性。本文将探讨AI论文写作工具为何能产出如此高原创度的内容&a…

欢迎观看在线直播|李航和张志华等嘉宾解读:人工智能和诺贝尔奖相遇,是偶然还是必然?

人工智能是新一轮产业革命的核心技术&#xff0c;受到了各个国家和不同领域人士的高度重视。不仅如此&#xff0c;它还为基础科学的研究创造出了新的研究范式。诺贝尔奖是科学界最著名的奖项之一&#xff0c;可谓是万众瞩目。2024年的诺贝尔物理奖和化学奖均授予了具有人工智能…

mysql的各种存储引擎

文章目录 前言1. InnoDB特点 2. MyISAM特点innodb与myisam引擎之间的区别 3. MEMORY特点 4. ARCHIVE特点 5. NDBCluster特点 6. FEDERATED特点 7. CSV特点 总结 前言 MySQL 支持多种存储引擎&#xff0c;每种引擎都有其独特的功能和适用场景。存储引擎是指数据库管理系统用来存…

Apache Seatunnel Zeta引擎-启动脚本分析

Apache SeaTunnel Zeta引擎的集群模式启动的第一步是执行bin/seatunnel-cluster.sh脚本&#xff0c;所以先来学习下这个脚本。 脚本执行流程分析 脚本简要注释 #!/bin/bash # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license a…

【Tinymce】富文本编辑器在vue项目中的使用;引入付费格式刷,上传视频、图片

引言 富文本编辑器有很多&#xff0c;对比了一下&#xff0c;还是决定用tinymce&#xff08;号称宇宙最强&#xff09;&#xff0c;基础的插件确实好用&#xff0c;但是一些更好用的插件&#xff0c;比如格式刷等都是高级版&#xff08;付费&#xff09;&#xff0c;当然也有人…

day-69 构成整天的下标对数目 II

思路 根据题意&#xff0c;每个元素可以重复使用&#xff0c;所以只需统计对24取余后值值相同的个数&#xff0c;如当前数字对24取余后是3&#xff0c;那么只需知道取余后为21的元素个数即可知道当前元素可与&#xff0c;多少个元素构成整天的下标的数目 解题过程 从左往右遍历…

数据结构编程实践20讲(Python版)—20并查集

本文目录 20 并查集&#xff08;Union-Find Set&#xff09;S1 说明并查集的定义并查集基本操作并查集优化并查集特点应用领域 S2 示例S3 问题1&#xff1a;朋友圈问题S4 问题2&#xff1a;网络连接恢复问题S5 问题3&#xff1a;随机生成迷宫 往期链接 01 数组02 链表03 栈04 …