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}