Java 实现发送 HTTP 请求,系列文章:
《Java使用原生HttpURLConnection实现发送HTTP请求》
《Java使用HttpClient5实现发送HTTP请求》
《SpringBoot使用RestTemplate实现发送HTTP请求》
1、RestTemplate 的介绍
RestTemplate 是 Spring 框架提供的一个用于访问 RESTful 服务的客户端工具,它简化了与 RESTful 服务的交互,并提供了一系列方便的方法来发送 HTTP 请求、处理响应以及处理错误。
RestTemplate 的主要特点:
- 简化的API:RestTemplate 提供了一组简单易用的方法,使得发送HTTP请求变得非常简单和直观。
- 支持多种HTTP方法:RestTemplate 支持 GET、POST、PUT、DELETE 等多种 HTTP 方法,可以满足不同的业务需求。
- 内置的序列化和反序列化支持:RestTemplate 可以自动将请求和响应的 JSON/XML 数据转换为 Java 对象,简化了数据的处理过程。
- 异常处理:RestTemplate 提供了对 HTTP 请求过程中可能出现的异常进行处理的机制,方便开发者进行错误处理和容错机制的实现。
- 可扩展性:RestTemplate 可以通过自定义的 HttpMessageConverter 来支持更多的数据格式和序列化方式。
- 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}


















