Java 实现发送 HTTP 请求,系列文章:
《Java使用原生HttpURLConnection实现发送HTTP请求》
《Java使用HttpClient5实现发送HTTP请求》
《SpringBoot使用RestTemplate实现发送HTTP请求》
1、HttpURLConnection 类的介绍
HttpURLConnection 是 Java 提供的原生标准的用于发送 HTTP 请求和接收 HTTP 响应的一个类,它位于 java.net 包下,并继承了 URLConnection 类。
HttpURLconnection 是基于 HTTP 协议的,支持 get,post,put,delete 等各种请求方式,最常用的就是 get 和 post。
URLConnection 提供了一组方法来建立与 URL 之间的连接、发送请求和接收响应。
以下是 HttpURLConnection 类常用的方法:
方法 | 说明 |
---|---|
openConnection() | 用于打开与 URL 的连接,返回一个 URLConnection 对象。 |
setRequestMethod(String method) | 设置请求方法,如 GET、POST 等。 |
setRequestProperty(String key, String value) | 设置请求属性,如请求头参数。 |
getRequestMethod() | 获取当前请求的方法。 |
getRequestProperty(String key) | 获取指定请求属性的值。 |
connect() | 建立与URL的连接。 |
getInputStream() | 获取输入流,用于接收响应数据。 |
getOutputStream() | 获取输出流,用于发送请求数据。 |
getResponseCode() | 获取响应的状态码。 |
getHeaderField(String name) | 获取指定响应头字段的值。 |
setDoInput(boolean doinput) | 设置是否从 URLConnection 读入,默认为true。 |
setDoOutput(boolean dooutput) | 设置是否向 URLConnection 输出,默认为false。 |
setInstanceFollowRedirects(boolean followRedirects) | 设置是否自动执行重定向,默认为true。 |
disconnect() | 断开与URL的连接。 |
2、创建 HttpURLConnection 工具类
通过将常用的方法封装到工具类中,可以避免重复编写相同的代码,从而提高代码的复用性。
基于 HttpURLConnection 的 HTTP 请求工具类:
package com.pjb.consumer.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
/**
* 基于 HttpURLConnection 的 HTTP 请求工具类
* @author pan_junbiao
**/
public class HttpURLConnectionUtil
{
// 超时时间
private final static int timeOut = 60000; //60秒
/**
* 发送 GET 请求并获取响应数据
*
* @param url 请求地址
* @param params 请求参数
* @return 响应数据字符串
*/
public static String doGet(String url, Map<String, String> params)
{
HttpURLConnection connection = null;
BufferedReader reader = null;
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);
}
URL targetUrl = new URL(stringBuffer.toString());
// 2、建立链接
connection = (HttpURLConnection) targetUrl.openConnection();
// 设置请求方法为 GET
connection.setRequestMethod("GET");
// 设置连接超时
connection.setConnectTimeout(timeOut);
// 设置读取响应超时
connection.setReadTimeout(timeOut);
// 3、获取响应结果
StringBuilder response = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null)
{
response.append(line);
}
return response.toString();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
//释放资源
releaseResource(connection, null, reader);
}
return null;
}
/**
* 发送 POST 请求并获取响应数据
*
* @param url 请求地址
* @param params 请求参数
* @return 响应数据字符串
*/
public static String doPost(String url, Map<String, String> params)
{
HttpURLConnection connection = null;
OutputStream outputStream = null;
BufferedReader reader = null;
try
{
// 1、创建 URL 对象
URL targetUrl = new URL(url);
// 2、建立链接
connection = (HttpURLConnection) targetUrl.openConnection();
// 设置请求方法为 POST
connection.setRequestMethod("POST");
// 设置连接超时
connection.setConnectTimeout(timeOut);
// 设置读取响应超时
connection.setReadTimeout(timeOut);
// 设置请求头部为默认:URL编码表单数据格式
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// 允许写入输出流
connection.setDoOutput(true);
// 禁用缓存
connection.setUseCaches(false);
// 3、写入请求体
outputStream = connection.getOutputStream();
StringBuffer payload = new StringBuffer();
if (params != null && !params.isEmpty())
{
for (Map.Entry<String, String> entry : params.entrySet())
{
payload.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
payload.deleteCharAt(payload.length() - 1);
}
outputStream.write(payload.toString().getBytes());
outputStream.flush();
outputStream.close();
// 4、获取响应结果
StringBuilder response = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
// 读取响应数据
while ((line = reader.readLine()) != null)
{
response.append(line);
}
return response.toString();
} catch (IOException e)
{
e.printStackTrace();
} finally
{
//释放资源
releaseResource(connection, outputStream, reader);
}
return null;
}
/**
* 发送 JSON 格式的 POST 请求并获取响应数据
*
* @param url 请求地址
* @param jsonParam JSON格式的请求参数
* @return 响应数据字符串
*/
public static String doJsonPost(String url, String jsonParam)
{
HttpURLConnection connection = null;
OutputStream outputStream = null;
BufferedReader reader = null;
try
{
// 1、创建 URL 对象
URL targetUrl = new URL(url);
// 2、建立链接
connection = (HttpURLConnection) targetUrl.openConnection();
// 设置请求方法为 POST
connection.setRequestMethod("POST");
// 设置请求头部为 JSON 格式
connection.setRequestProperty("Content-Type", "application/json");
// 设置连接超时
connection.setConnectTimeout(timeOut);
// 设置读取响应超时
connection.setReadTimeout(timeOut);
// 允许向服务器发送数据
connection.setDoOutput(true);
// 3、向服务器发送 JSON 数据
outputStream = connection.getOutputStream();
outputStream.write(jsonParam.getBytes());
outputStream.flush();
// 4、获取响应结果
StringBuffer response = new StringBuffer();
int responseCode = connection.getResponseCode();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null)
{
response.append(line);
}
return response.toString();
} catch (Exception e)
{
e.printStackTrace();
} finally
{
//释放资源
releaseResource(connection, outputStream, reader);
}
return null;
}
/**
* 释放资源
*/
private static void releaseResource(HttpURLConnection connection, OutputStream outputStream, BufferedReader reader)
{
if (connection != null)
{
try
{
connection.disconnect();
} catch (Exception e)
{
System.out.println("连接关闭失败");
}
}
if (outputStream != null)
{
try
{
outputStream.close();
} catch (IOException e)
{
System.out.println("输出流关闭失败");
}
}
if (reader != null)
{
try
{
reader.close();
} catch (IOException e)
{
System.out.println("输入流关闭失败");
}
}
}
}
3、综合实例
【实例】实现用户信息的查询、新增、修改、删除接口,并使用 HttpURLConnection 实现接口的请求。
(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,String userName)
{
if (userId <= 0)
{
//使用:全局异常处理
throw new ApiResponseException(ApiResponseCode.PARAMETER_ERROR);
}
//使用:统一返回值
return new ApiResponseResult(ApiResponseCode.SUCCESS, true);
}
}
(2)使用 HttpURLConnection 发送 Get 请求,查询用户信息。
/**
* 使用 HttpURLConnection 发送 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 = HttpURLConnectionUtil.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)使用 HttpURLConnection 发送 JSON 格式的 POST 请求,新增用户信息。
/**
* 使用 HttpURLConnection 发送 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 = HttpURLConnectionUtil.doJsonPost(url, json);
System.out.println("响应结果:" + httpResult);
}
执行结果:
响应结果:{"code":200000,"message":"操作成功","data":true}
(4)使用 HttpURLConnection 发送 POST 请求,删除用户信息。
/**
* 使用 HttpURLConnection 发送 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 = HttpURLConnectionUtil.doPost(url, params);
System.out.println("响应结果:" + httpResult);
}
执行结果:
响应结果:{"code":200000,"message":"操作成功","data":true}