SpringBoot使用RestTemplate实现发送HTTP请求

 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}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【java】抽象类和接口(了解,进阶,到全部掌握)

各位看官早安午安晚安呀 如果您觉得这篇文章对您有帮助的话 欢迎您一键三连&#xff0c;小编尽全力做到更好 欢迎您分享给更多人哦 大家好我们今天来学习Java面向对象的的抽象类和接口&#xff0c;我们大家庭已经来啦~ 一&#xff1a;抽象类 1.1:抽象类概念 在面向对象的概念中…

12寸FAB厂试产到量产实现无纸化要素之软硬件

在12寸先进封装半导体车间从试产到量产的过程中&#xff0c;实现生产过程无纸化&#xff0c;需要综合考虑软硬件的配置。以下是一些关键的规划建议&#xff1a; 1、生产文档管理系统&#xff08;PDM&#xff09;&#xff1a; 采用基于SOLIDWORKS PDM开发的无纸化方案&#xf…

uniapp 整合 OpenLayers - 加载Geojson数据(在线、离线)

Geojson数据是矢量数据&#xff0c;主要是点、线、面数据集合 Geojson数据获取&#xff1a;DataV.GeoAtlas地理小工具系列 实现代码如下&#xff1a; <template><!-- 监听变量 operation 的变化&#xff0c;operation 发生改变时&#xff0c;调用 openlayers 模块的…

Java面试场景题(1)---如何使用redis记录上亿用户连续登陆天数

感谢uu们的观看&#xff0c;话不多说开始~ 对于这个问题&#xff0c;我们需要先来了解一下~ 海量数据都可以用bitmap来存储&#xff0c;因为占得内存小&#xff0c;速度也很快 我大概计算了一下~ 完全够&#xff1a;String类型512M 1byte 8个bit位 8个状态 512M1024byt…

数据库性能测试报告总结模板

1计划概述 目的&#xff1a;找出系统潜在的性能缺陷 目标&#xff1a;从安全&#xff0c;可靠&#xff0c;稳定的角度出发&#xff0c;找出性能缺陷&#xff0c;并且找出系统最佳承受并发用户数&#xff0c;以及并发用户数下长时间运行的负载情况&#xff0c;如要并发100用户&a…

CTFHUB技能树之SQL——字符型注入

开启靶场&#xff0c;打开链接&#xff1a; 直接指明是SQL字符型注入&#xff0c;但还是来判断一下 &#xff08;1&#xff09;检查是否存在注入点 1 and 11# 返回正确 1 and 12# 返回错误 说明存在SQL字符型注入 &#xff08;2&#xff09;猜字段数 1 order by 2# 1 order…

颠覆编程!通义灵码、包阅AI、CodeGeeX三大AI助手解锁无限潜力!

随着科技的疾速前行&#xff0c;人工智能&#xff08;AI&#xff09;辅助编程工具已跃然成为软件开发领域及编程爱好者群体中不可或缺的得力助手。这些融入了尖端智能化算法的工具&#xff0c;不仅深刻改变了编程工作的面貌&#xff0c;通过自动化和优化手段显著提升了编程效率…

GJS-WCP

不懂的就问&#xff0c;但我也是二把手......哭死 web GJS-ezssti 很常规的ssti模板注入&#xff0c;只过滤了"/","flag"。 过滤了/,flag 可以利用bash的特性绕过&#xff0c;如字符串截取&#xff0c;环境变量等等。payload1: {{url_for.__globals__[…

柔性数组的使用

//柔性数组的使用 #include<stdio.h> #include<stdlib.h> #include<errno.h> struct s {int i;int a[]; }; int main() {struct s* ps (struct s*)malloc(sizeof(struct s) 20 * sizeof(int));if (ps NULL){perror("malloc");return 1;}//使用这…

react18中在列表项中如何使用useRef来获取每项的dom对象

在react中获取dom节点都知道用ref&#xff0c;但是在一个列表循环中&#xff0c;这样做是行不通的&#xff0c;需要做进一步的数据处理。 实现效果 需求&#xff1a;点击每张图片&#xff0c;当前图片出现在可视区域。 代码实现 .box{border: 1px solid #000;list-style: …

Math类、System类、Runtime类、Object类、Objects类、BigInteger类、BigDecimal类

课程目标 能够熟练使用Math类中的常见方法 能够熟练使用System类中的常见方法 能够理解Object类的常见方法作用 能够熟练使用Objects类的常见方法 能够熟练使用BigInteger类的常见方法 能够熟练使用BigDecimal类的常见方法 1 Math类 1.1 概述 tips&#xff1a;了解内容…

Java | Leetcode Java题解之第493题翻转对

题目&#xff1a; 题解&#xff1a; class Solution {public int reversePairs(int[] nums) {Set<Long> allNumbers new TreeSet<Long>();for (int x : nums) {allNumbers.add((long) x);allNumbers.add((long) x * 2);}// 利用哈希表进行离散化Map<Long, Int…

【JAVA】第三张_Eclipse下载、安装、汉化

简介 Eclipse是一种流行的集成开发环境&#xff08;IDE&#xff09;&#xff0c;可用于开发各种编程语言&#xff0c;包括Java、C、Python等。它最初由IBM公司开发&#xff0c;后来被Eclipse Foundation接手并成为一个开源项目。 Eclipse提供了一个功能强大的开发平台&#x…

AI 编译器学习笔记之四 -- cann接口使用

1、安装昇腾依赖 # CANN发布件地址 https://cmc.rnd.huawei.com/cmcversion/index/releaseView?deltaId10274626629404288&isSelectSoftware&url_datarun Ascend-cann-toolkit_8.0.T15_linux-aarch64.run Ascend-cann-nnal_8.0.T15_linux-aarch64.run Ascend-cann-ker…

当下大语言模型(LLM)应用的架构介绍

想要构建你的第一个大语言模型应用&#xff1f;这里有你需要了解的一切&#xff0c;以及你今天就能开始探索的问题领域。 LLM 应用架构 我们的目标是让你能够自由地使用大语言模型进行实验、打造自己的应用&#xff0c;并挖掘那些尚未被人注意的问题领域。为此&#xff0c;Git…

数据类型的通用操作

#通用操作有&#xff1a;for语句遍历&#xff0c;len()统计元素个数&#xff0c;是数据类型间的相互转换&#xff0c;元素的排序&#xff08;正反向&#xff09; 1.for语句遍历若遍历字典则 只去字典中的key(即名词) 2.各数据类型间的数据转换&#xff08;若为字典转化为列表…

2024年软件设计师中级(软考中级)详细笔记【7】面向对象技术(上)(分值10+)

目录 前言第7章 面向对象技术 &#xff08;上&#xff09;7.1 面向对象基础(3-4分&#xff09;7.1.1 面向对象的基本概念7.1.2 面向对象分析&#xff08;熟记&#xff09;7.1.3 面向对象设计7.1.4 面向对象程序设计7.1.5 面向对象测试 7.2 UML(3~4分)7.2.1 事务7.2.2 关系7.2.2…

超详细JDK安装+环境配置教程

安装jdk 1.首先在JDK官网进行下载 JDK会默认安装在C盘 program file文件下 2.并且在JDK安装的过程中会提示安装JRE JDK和JRE会安装在同一目录下 JDK通过命令行进行使用 JDK的目录 以下是JDK对应的目录 bin:存放可执行程序 其中包含java javac命令 Include&#xff1a;本地…

013_django基于大数据的高血压人群分析系统2024_dcb7986h_055

目录 系统展示 开发背景 代码实现 项目案例 获取源码 博主介绍&#xff1a;CodeMentor毕业设计领航者、全网关注者30W群落&#xff0c;InfoQ特邀专栏作家、技术博客领航者、InfoQ新星培育计划导师、Web开发领域杰出贡献者&#xff0c;博客领航之星、开发者头条/腾讯云/AW…

react-native 安装 自学笔记(踩坑点)

react-native环境安装搭建注意点 安装环境文档地址&#xff1a; Android 原生UI组件 React Native 中文网&#xff08;中文网可能有些信息没有外文的更新及时&#xff09; 1.必须要安装node 和 jdk 坑点&#xff1a;node版本18/18 jdk版本文档要求17&#xff0c;但是我clo…