利用HttpURLConnection发送post请求上传文件

本文详细介绍如何使用Java的HttpURLConnection实现文件上传功能,并提供了一个具体的示例代码。通过解析HTTP请求内容,展示了表单数据和文件是如何被封装并发送的。

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

在页面里实现上传文件不是什么难事,写个form,加上enctype = "multipart/form-data",在写个接收的就可以了,没什么难的,如果要用java.net.HttpURLConnection来实现文件上传,还真有点搞头.:-)

1.先写个servlet把接收到的 HTTP 信息保存在一个文件中, 看一下 form 表单到底封装了什么样的信息。

public void doPost(HttpServletRequest request, HttpServletResponse response)
           throws ServletException, IOException {
       //获取输入流,是HTTP协议中的实体内容
       ServletInputStream  in=request.getInputStream();
       //缓冲区
       byte buffer[]=new byte[1024];
       FileOutputStream out=new FileOutputStream("d:\\test.log");
       int len=sis.read(buffer, 0, 1024);
       //把流里的信息循环读入到file.log文件中
       while( len!=-1 ){
           out.write(buffer, 0, len);
           len=in.readLine(buffer, 0, 1024);

       }
       out.close();
       in.close();
    }

 来一个form表单。

  <form name="upform" action="upload.do" method="POST"
            enctype="multipart/form-data">
            参数<input type="text" name="username"/><br/>
            文件1<input type="file" name="file1"/><br/>
            文件2<input type="file" name="file2"/><br/>
            <input type="submit" value="Submit" />
            <br />
     </form>

假如我参数写的内容是hello word,然后二个文件是二个简单的txt文件,上传后test.log里如下

-----------------------------7da2e536604c8
Content-Disposition: form-data; name="username"

hello word
-----------------------------7da2e536604c8
Content-Disposition: form-data; name="file1"; filename="D:\haha.txt"
Content-Type: text/plain

haha
  hahaha
-----------------------------7da2e536604c8
Content-Disposition: form-data; name="file2"; filename="D:\huhu.txt"
Content-Type: text/plain

messi 
huhu
-----------------------------7da2e536604c8--

 

 研究下规律发现有如下几点特征

1.第一行是“ -----------------------------7d92221b604bc ”作为分隔符,然后是“ \r\n ” 回车换行符。 这个7d92221b604bc 分隔符浏览器是随机生成的。

2.第二行是Content-Disposition: form-data; name="file2"; filename="D:\huhu.txt";name=对应input的name值,filename对应要上传的文件名(包括路径在内),

3.第三行如果是文件就有Content-Type: text/plain;这里上传的是txt文件所以是text/plain,如果上穿的是jpg图片的话就是image/jpg了,可以自己试试看看。

然后就是回车换行符。

4.在下就是文件或参数的内容或值了。如:hello word。

5.最后一行是-----------------------------7da2e536604c8--,注意最后多了二个--;

 

有了这些就可以使用HttpURLConnection来实现上传文件功能了

public void upload(){
		List<String> list  = new ArrayList<String>();  //要上传的文件名,如:d:\haha.doc.你要实现自己的业务。我这里就是一个空list.
		try {
			String BOUNDARY = "---------7d4a6d158c9"; // 定义数据分隔线
			URL url = new URL("http://localhost/JobPro/upload.do");
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
			conn.setRequestProperty("Charsert", "UTF-8"); 
			conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
			
			OutputStream out = new DataOutputStream(conn.getOutputStream());
			byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();// 定义最后数据分隔线
			int leng = list.size();
			for(int i=0;i<leng;i++){
				String fname = list.get(i);
				File file = new File(fname);
				StringBuilder sb = new StringBuilder();  
				sb.append("--");  
				sb.append(BOUNDARY);  
				sb.append("\r\n");  
				sb.append("Content-Disposition: form-data;name=\"file"+i+"\";filename=\""+ file.getName() + "\"\r\n");  
				sb.append("Content-Type:application/octet-stream\r\n\r\n");  
				
				byte[] data = sb.toString().getBytes();
				out.write(data);
				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);
				}
				out.write("\r\n".getBytes()); //多个文件时,二个文件之间加入这个
				in.close();
			}
			out.write(end_data);
			out.flush();  
			out.close(); 
			
			// 定义BufferedReader输入流来读取URL的响应
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line = null;
			while ((line = reader.readLine()) != null) {
				System.out.println(line);
			}

		} catch (Exception e) {
			System.out.println("发送POST请求出现异常!" + e);
			e.printStackTrace();
		}
	}

 至于接收文件上传,可以浏览本博客中文章利用commons-fileupload 实现文件上传终极版及commons-fileupload和commons-io包关系

 

 

### 如何使用Java发送文件POST请求 为了实现通过Java发送文件POST请求,可以利用`HttpURLConnection`类来构建HTTP客户端并处理文件上传操作。下面是一个具体的例子,展示了如何设置连接以及准备和执行包含文件数据在内的POST请求。 #### 准备工作 首先确保项目中有权限访问网络资源,并导入必要的包: ```java import java.io.*; import java.net.HttpURLConnection; import java.net.URL; ``` 接着定义用于创建边界字符串的方法,这有助于区分多部分表单字段的内容: ```java private static final String BOUNDARY = "==="; public static void main(String[] args) throws Exception { URL url = new URL("http://example.com/upload"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 设置通用属性 connection.setDoOutput(true); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); try ( DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()); FileInputStream inputStream = new FileInputStream(new File("/path/to/file")) ) { // 添加二进制文件作为一部分 multipart 数据的一部分 writePart(outputStream, "fileParamName", "/path/to/file", inputStream); int responseCode = connection.getResponseCode(); System.out.println("\nSending 'POST' request to URL : " + url); System.out.println("Response Code : " + responseCode); BufferedReader in = new BufferedReader( new InputStreamReader(connection.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); // 打印结果 System.out.println(response.toString()); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e.getCause()); } } // 辅助方法用来写入每一个 part 到 output stream 中去. private static void writePart(DataOutputStream out, String paramName, String fileName, InputStream content) throws IOException { StringBuilder sb = new StringBuilder(); sb.append("--").append(BOUNDARY).append("\r\n"); sb.append("Content-Disposition: form-data; name=\"") .append(paramName) .append("\"; filename=\"") .append(fileName) .append("\"\r\n\r\n"); out.writeBytes(sb.toString()); byte[] buffer = new byte[8192]; for (int length; (length = content.read(buffer)) > 0;) { out.write(buffer, 0, length); } out.writeBytes("\r\n"); // 结束当前part的数据流 } ``` 此代码片段说明了怎样配置一个支持文件上传功能的HTTP POST请求[^1]。注意这里假设服务器端能够接收名为`fileParamName`参数名下的文件对象;实际应用时应根据API文档调整相应的名称和其他细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值