HttpURLConnection 上传文件

package tools.fileupload;


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;


import tools.MyUUID;


 


public class UrlFileUpload {


/**
* 发送请求

* @param url
*            请求地址
* @param filePath
*            文件在服务器保存路径(这里是为了自己测试方便而写,可以将该参数去掉)
* @return
* @throws IOException
*/
public static int send(String url, File file) throws IOException { 
/**
* 第一部分
*/
URL urlObj = new URL(url);
HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();


/**
* 设置关键值
*/
con.setRequestMethod("POST"); // 以Post方式提交表单,默认get方式
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false); // post方式不能使用缓存


// 设置请求头信息
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Charset", "UTF-8");


// 设置边界
String BOUNDARY = "----------" + MyUUID.getUUID();
con.setRequestProperty("Content-Type", "multipart/form-data; boundary="
+ BOUNDARY); 

// 请求正文信息


// 第一部分:
StringBuilder sb = new StringBuilder();
sb.append("--"); // 必须多两道线
sb.append(BOUNDARY);
sb.append("\r\n");
sb.append("Content-Disposition: form-data;name=\"file\";filename=\""+ file.getName() + "\"\r\n");
sb.append("Content-Type:application/octet-stream\r\n\r\n");


byte[] head = sb.toString().getBytes("utf-8"); 

// 获得输出流 
OutputStream out = new DataOutputStream(con.getOutputStream());
out.write(head);


// 文件正文部分
DataInputStream in = new DataInputStream(new FileInputStream(file));
int bytes = 0;
byte[] bufferOut = new byte[1024];
while ((bytes = in.read(bufferOut)) != -1) {
out.write(bufferOut, 0, bytes);
}
in.close();


// 结尾部分
byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线


out.write(foot);


out.flush();
out.close();


/**
* 读取服务器响应,必须读取,否则提交不成功
*/


return con.getResponseCode();


/**
* 下面的方式读取也是可以的
*/


// try {
// // 定义BufferedReader输入流来读取URL的响应
// BufferedReader reader = new BufferedReader(new InputStreamReader(
// con.getInputStream()));
// String line = null;
// while ((line = reader.readLine()) != null) {
// System.out.println(line);
// }
// } catch (Exception e) {
// System.out.println("发送POST请求出现异常!" + e);
// e.printStackTrace();
// }



 
}
### 使用 HttpURLConnection 实现文件上传Java 示例 以下是基于提供的参考资料以及常见实践的一个完整示例代码,用于通过 `HttpURLConnection` 向服务器上传文件。 #### 文件上传的核心逻辑 为了实现文件上传功能,通常需要构建一个多部分表单 (`multipart/form-data`) 请求。此请求允许将二进制数据与其他字段一起发送给服务器。下面展示了一个完整的代码片段: ```java import java.io.*; import java.net.HttpURLConnection; import java.net.URL; public class FileUploader { private static final String LINE_FEED = "\r\n"; private static final String BOUNDARY_PREFIX = "--"; public static void uploadFile(String requestUrl, String filePath, String paramName) throws Exception { URL url = new URL(requestUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 设置连接属性 connection.setDoOutput(true); // 允许输出 connection.setDoInput(true); // 允许输入 connection.setUseCaches(false); // 不使用缓存 connection.setRequestMethod("POST"); // POST 方法 connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + generateBoundary()); try (OutputStream outputStream = connection.getOutputStream(); DataOutputStream writer = new DataOutputStream(outputStream)) { // 构建多部分表单头部 StringBuilder formDataHeader = new StringBuilder(BOUNDARY_PREFIX); formDataHeader.append(generateBoundary()).append(LINE_FEED) .append("Content-Disposition: form-data; name=\"").append(paramName).append("\"; filename=\"") .append(new File(filePath).getName()).append("\"").append(LINE_FEED) .append("Content-Type: application/octet-stream").append(LINE_FEED) .append(LINE_FEED); writer.writeBytes(formDataHeader.toString()); // 将文件内容写入流中 FileInputStream inputStream = null; try { inputStream = new FileInputStream(filePath); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { writer.write(buffer, 0, bytesRead); } } finally { if (inputStream != null) { inputStream.close(); } } // 添加结束符 writer.writeBytes(LINE_FEED); writer.writeBytes(BOUNDARY_PREFIX + generateBoundary() + "--" + LINE_FEED); // 发送并获取响应 InputStream responseStream = new BufferedInputStream(connection.getInputStream()); BufferedReader reader = new BufferedReader(new InputStreamReader(responseStream)); String line; StringBuilder responseStringBuilder = new StringBuilder(); while ((line = reader.readLine()) != null) { responseStringBuilder.append(line).append("\n"); } System.out.println("Response from server:\n" + responseStringBuilder.toString()); } catch (Exception e) { throw e; } finally { connection.disconnect(); } } private static String generateBoundary() { return "===" + System.currentTimeMillis() + "==="; } } ``` 上述代码实现了以下功能: - 创建 HTTP 连接对象,并设置其为支持输出和输入模式[^1]。 - 配置 Content-Type 头部以指示这是一个 multipart 表单提交。 - 编写文件头信息(包括名称、MIME 类型等),并将实际文件内容逐块读取后写入输出流[^2]。 - 最终关闭资源并打印来自服务端的反馈消息。 #### 关于中文乱码处理 如果遇到涉及字符串编码的问题,则需特别注意以下几点: - 当调用 `String.getByte()` 方法时,默认采用平台特定编码可能会引发兼容性问题;因此建议显式指明 UTF-8 编码标准,即改用 `content.getBytes("utf-8")` 来替代简单形式[^2]。 此外还需确认目标 Web 应用程序能够正确解析所接收的数据包及其内部字符集定义。 --- ### 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值