Java HTTP 协议上传文件


HTTP 上传文件需要在 Header 加入


Connection: keep-alive
Content-Length: 11921
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx5UZnY5yoibtY0sa


其中 Content-Typemultipart/form-data 之余,要加一个 boundaryboundary 是自定义的分隔界限,这个界限是用来分隔上传的多个文件或表单讯息 (每一部份是一个 Part)。上面的 boundary Chrome 生成的界限。


Chrome 用界限包含单个文件后如下


------WebKitFormBoundaryx5UZnY5yoibtY0sa
Content-Disposition: form-data; name="media"; filename="hello.jpg"
Content-Type: image/jpeg

${我是文件的內容}

------WebKitFormBoundaryx5UZnY5yoibtY0sa--


可以看到原來 boundary 只有 「----」(4个),而包含数据时会自动再加上「--」(2 个),这边就变成了 6 个。而标志所有结束亦是一个「--」(2 个)。

另外有兩行关於上传数据的讯息,这个讯息根据上传数据而有不同。如果是文件 Content-Dispositionname 就是 <input> 的 name,filename 則是文件名。Content-Type 是 MIME 类型。

只要只要将文件数据前後加上应有的界限和讯息,就可以以 HTTP 上传文件。它的規則是


--${boundary}
\r\n
Content-Disposition: form-data; name=${input_name}; filename=${filename}
\r\n
Content-Type: ${mime}
\r\n\r\n
${我是文件的內容}
\r\n\r\n
--${boundary}[如果所有結束再加--]
\r\n


实现可以参考 http://1147295574-qq-com.iteye.com/blog/2005540。



public static InputStream upload(String urlstr, String filepath, String name, String filename, String mime) throws IOException {  	  
	    File file = new File(filepath);  
	    if (file.exists() == false){
	    	throw new FileNotFoundException(filepath);
	    }

	    URL url = new URL(urlstr);  
	    HttpURLConnection con = (HttpURLConnection) url.openConnection();  
	  
	    con.setRequestMethod("POST"); // 以Post方式提交表单,默认get方式  
	    con.setDoInput(true);  
	    con.setDoOutput(true);  
	    con.setUseCaches(false); // POST 方式不能使用缓存  

	    // 设置边界  
	    String boundary = "------" + System.currentTimeMillis();
	    name = name == null ? "file" : name;
	    filename = filename == null ? file.getName() : filename;
	    mime = mime == null ? "application/octet-stream" : mime;
	    
	    
	    
	
	    // =========== 请求正文信息 ==========  
	    // 表头  
	    StringBuilder payload = new StringBuilder();  
	    payload.append("--"); // 必须多两道线  
	    payload.append(boundary);  
	    payload.append("\r\n");  
	    payload.append("Content-Disposition: form-data; name=\"").append(name).append("\"; filename=\"").append(filename).append("\"\r\n");  
	    payload.append("Content-Type: ").append(mime).append("\r\n\r\n");
	    // 表尾
	    String tail = "\r\n--" + boundary + "--\r\n";
	    byte[] payload_bytes = payload.toString().getBytes("UTF-8");
	    byte[] tail_bytes = tail.getBytes("UTF-8");
	    long content_length = payload_bytes.length + file.length() + tail_bytes.length;
	    
	    // 设置 HTTP Header   
	    con.setRequestProperty("Connection", "keep-alive");  
	    con.setRequestProperty("Charset", "UTF-8");  
	    con.setRequestProperty("Content-Type", "multipart/form-data; boundary="+ boundary);
	    con.setRequestProperty("Content-Length", Long.toString(content_length));
	  
	    
	    OutputStream out = null;
	    InputStream filein = null;
	    try {
	    	out = con.getOutputStream();
	    	filein = new FileInputStream(file);
	    	
	    	
		    out.write(payload_bytes); 
		    // 文件正文部分
		    int bytecount = 0;  
		    byte[] buffer = new byte[2 * 4096];  
		    while(true){
		    	bytecount = filein.read(buffer);
		    	if (bytecount <= 0) break;
		    	out.write(buffer, 0, bytecount);
		    }
		    
		    
		    out.write(tail_bytes);
		    out.flush();  
		    
	    } catch (IOException ex){
	    	throw ex;
	    } finally {
	        if (filein != null) filein.close();
	    	if (out != null) out.close();
	    }
		return con.getInputStream();  
	}



你可能感兴趣的:(Java HTTP 协议上传文件)