一个手写的 http client

本文分享了一段自定义的HTTP客户端代码实现,包括GET、POST、PUT和DELETE请求的发送与响应数据的获取,详细解释了每个方法的实现逻辑与关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public class HTTPClient {
	
	public static final String GET = "GET";
	public static final String POST = "POST";
	public static final String PUT = "PUT";
	public static final String DELETE = "DELETE";
	
	public static String getData(String path) throws Exception {
		String responseData = visitWithoutParam(path, GET);
		return responseData;
	}
	
	public static String postData(String path, String data) throws Exception {
		String responseData = visitWithParam(path, POST, data);
		return responseData;
	}
	
	public static String putData(String path, String data) throws Exception {
		return "To do put data";
	}
	
	public static String deleteData(String path) throws Exception {
		return "To do delete data";
	}
	
	public static String visitWithParam(String path, String method, String body) throws Exception{
		InputStream inputStream = null;
		BufferedReader bufferedReader = null;
		
		try {
			URL url = new URL(path);
			HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
			httpURLConnection.setDoInput(true);
			httpURLConnection.setDoOutput(true);
			httpURLConnection.setUseCaches(false);
			
			httpURLConnection.setRequestMethod(method);
			httpURLConnection.setRequestProperty("Content-Type", "application/json");
			httpURLConnection.setRequestProperty("charset", "utf-8");
			httpURLConnection.setRequestProperty("Content-Length", Integer.toString(body.getBytes().length));
			
			DataOutputStream dataOutputStream = new DataOutputStream(httpURLConnection.getOutputStream());
			dataOutputStream.writeBytes(body);
			dataOutputStream.flush();
			dataOutputStream.close();
			
			inputStream = httpURLConnection.getInputStream();
			bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
			StringBuilder stringBuilder = new StringBuilder();
			String line = null;
			
			while((line = bufferedReader.readLine()) != null)
				stringBuilder.append(line);
			
			return stringBuilder.toString();
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			// no need to change null actually
			try {
				if(bufferedReader != null) bufferedReader.close(); 
				if(inputStream != null) inputStream.close();
			} catch (Exception e){
				
			}
		}
	}
	
	public static String visitWithoutParam(String path, String method) throws Exception {
		InputStream inputStream = null;
		BufferedReader bufferedReader = null;
		
		URL url;
		try {
			url = new URL(path);
			HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
			httpURLConnection.setDoInput(true);
			httpURLConnection.setUseCaches(false);
			
			httpURLConnection.setRequestMethod(method);
			
			inputStream = httpURLConnection.getInputStream();
			bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
			
			StringBuilder stringBuilder = new StringBuilder();
			String line = null;
			
			while((line = bufferedReader.readLine()) != null)
				stringBuilder.append(line);
			
			return stringBuilder.toString();
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			try {
				if(bufferedReader != null) bufferedReader.close();
				if(inputStream != null) inputStream.close();
			} catch (Exception e) {
				
			}
		}
		
	}
}

 

自己很久以前写过的一段代码,当时忘记了 apache.httpclient 这个东西,结果又重新造了个轮子  

<think>我们正在手动实现一个HTTP客户端的POST请求。根据引用[3]和引用[4],我们知道HTTP POST请求将数据放在请求体中,并且需要设置合适的请求头(如Content-Type)。同时,引用[2]和引用[3]提到Java有多种方式发送HTTP POST请求,但这里要求手动实现,即不依赖第三方库(如Apache HttpClient、RestTemplate等),而是使用Java标准库(如java.net包)。 步骤: 1. 创建URL对象,指定目标URL。 2. 打开连接(HttpURLConnection)。 3. 设置请求方法为“POST”。 4. 设置请求头,例如Content-Type(根据发送的数据类型设置,如application/json、application/x-www-form-urlencoded等)。 5. 允许向连接输出(因为我们要发送请求体数据)。 6. 获取输出流,写入请求体数据。 7. 获取输入流,读取响应。 8. 处理响应并关闭连接。 注意:需要处理异常(IOException)。 示例:发送一个JSON格式的POST请求。 假设我们要发送的JSON数据为:{"name":"John", "age":30} 代码如下:</think>### Java 手动实现 HTTP Client POST 请求 下面分步骤说明如何用 Java 标准库手动实现 HTTP POST 请求,不依赖第三方库: #### 1. 核心实现步骤 ```java import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; public class ManualHttpPost { public static void main(String[] args) throws IOException { // 1. 创建目标URL URL url = new URL("https://example.com/api"); // 2. 打开HTTP连接 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // 3. 设置请求方法为POST conn.setRequestMethod("POST"); // 4. 设置请求头 conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); conn.setRequestProperty("Accept", "application/json"); // 5. 允许输出请求体 conn.setDoOutput(true); // 6. 准备JSON请求体 String jsonBody = "{\"username\":\"test\",\"password\":\"pass123\"}"; byte[] postData = jsonBody.getBytes(StandardCharsets.UTF_8); // 7. 发送请求体 try (OutputStream os = conn.getOutputStream()) { os.write(postData, 0, postData.length); } // 8. 获取响应码 int responseCode = conn.getResponseCode(); System.out.println("响应状态码: " + responseCode); // 9. 读取响应体 if (responseCode == HttpURLConnection.HTTP_OK) { try (BufferedReader br = new BufferedReader( new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) { StringBuilder response = new StringBuilder(); String responseLine; while ((responseLine = br.readLine()) != null) { response.append(responseLine.trim()); } System.out.println("响应体: " + response); } } else { System.err.println("请求失败: " + responseCode); } // 10. 断开连接 conn.disconnect(); } } ``` #### 2. 关键点说明 1. **`HttpURLConnection`**:Java 标准库提供的 HTTP 客户端实现类[^3] 2. **请求头设置**: - `Content-Type` 声明请求体格式(JSON/form-data等) - `Accept` 指定期望的响应格式 3. **请求体传输**: - 必须调用 `setDoOutput(true)` 启用输出 - 数据需转为字节流写入 `OutputStream` 4. **错误处理**: - 检查 HTTP 状态码(200表示成功) - 使用 `getErrorStream()` 读取错误响应体 5. **编码规范**: - 使用 `try-with-resources` 确保流关闭 - 明确指定 UTF-8 字符集避免乱码 #### 3. 不同数据格式示例 **表单数据格式**: ```java // 设置请求头 conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // 请求体格式 String formData = "username=test&password=pass123"; byte[] postData = formData.getBytes(StandardCharsets.UTF_8); ``` **文件上传**: ```java // 设置多部分边界 String boundary = "----WebKitFormBoundary" + System.currentTimeMillis(); conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); // 构建多部分请求体 StringBuilder body = new StringBuilder(); body.append("--").append(boundary).append("\r\n") .append("Content-Disposition: form-data; name=\"file\"; filename=\"test.txt\"\r\n\r\n") .append("文件内容...\r\n") .append("--").append(boundary).append("--"); ``` #### 4. 注意事项 1. **超时控制**: ```java conn.setConnectTimeout(5000); // 5秒连接超时 conn.setReadTimeout(10000); // 10秒读取超时 ``` 2. **HTTPS 支持**: - 需配置 `SSLContext` 处理证书 - 或使用 `HttpsURLConnection` 替代 3. **重定向处理**: ```java conn.setInstanceFollowRedirects(false); // 禁用自动重定向 ``` 4. **性能优化**: - 复用 `HttpURLConnection` 对象(需调用 `disconnect()`) - 启用 HTTP 持久连接: ```java System.setProperty("http.keepAlive", "true"); ``` ### 与 GET 请求的核心区别 1. **数据传输**: - POST 通过请求体传输数据,GET 通过 URL 参数传输[^4] - POST 支持更大数据量(URL 有长度限制) 2. **安全性**: - POST 数据不在 URL 中可见,但依然需要 HTTPS 加密 3. **缓存行为**: - GET 请求可被缓存,POST 默认不可缓存 > 提示:对于复杂场景(如 OAuth 签名、连接池管理),建议使用 Apache HttpClient 等专业库[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值