简单说下原理:
看看当网页上传文件时,到底发送了什么,文件是如何在报文中表示的
这是一个上传文件的网页
这是提交之后的报文
最重要的是下面这个
我们只要按着这个格式发送文件就行了
比如说要发送两个文件就这样写
------WebKitFormBoundaryUS75AnTOrrFe3vU2
Content-Disposition: form-data; name="userfile1"; filename="lantern.exe"
Content-Type: application/x-msdownload
------WebKitFormBoundaryUS75AnTOrrFe3vU2
Content-Disposition: form-data; name="userfile2"; filename="BaiduYunGuanjia.exe"
Content-Type: application/x-msdownload
------WebKitFormBoundaryUS75AnTOrrFe3vU2--
下面有代码
更新下HttpClient上传文件的代码,jar包去官网下载,原理还和之前的一样
package servlet;
import java.util.ArrayList;
import java.util.List;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.CharsetUtils;
import org.apache.http.util.EntityUtils;
public class HttpClientUploadFile {
@SuppressWarnings("deprecation")
public static void uploadFile(String url, List<String> uploadFiles) {
HttpClient httpClient = new DefaultHttpClient();// 开启一个客户端 HTTP 请求
HttpPost httpPost = new HttpPost(url);// 创建 HTTP POST 请求
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setCharset(Charset.forName("utf-8"));//设置请求的编码格式
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);// 设置浏览器兼容模式
builder.addTextBody("method", "POST");// 设置请求参数
builder.addTextBody("connection", "Keep-Alive");;// 设置请求参数
for (String uploadFile : uploadFiles) {
File file = new File(uploadFile);
if (file.exists()) {
//获得文件名
String fileName = uploadFile.substring(uploadFile.lastIndexOf(File.separator)+1);
builder.addBinaryBody(fileName, file);
}
}
HttpEntity entity = builder.build();// 生成 HTTP POST 实体
httpPost.setEntity(entity);// 设置请求参数
try {
HttpResponse response = httpClient.execute(httpPost);
System.out.println("发起请求的页面地址 " + httpPost.getRequestLine());
// 发起请求 并返回请求的响应
if (response != null) {
System.out.println("----------------------------------------");
// 打印响应状态
System.out.println(response.getStatusLine());
// 获取响应对象
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
// 打印响应长度
System.out.println("Response content length: "
+ resEntity.getContentLength());
// 打印响应内容
System.out.println(EntityUtils.toString(resEntity,
Charset.forName("UTF-8")));
// 销毁
EntityUtils.consume(resEntity);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
// 关闭连接,释放资源
httpClient.getConnectionManager().shutdown();
}
}
public static void main(String[] args) {
// 建立上传文件链表
List<String> uploadFiles = new ArrayList<String>();
uploadFiles.add("D://apache-tomcat-7.0.70-windows-x64.zip");
uploadFiles.add("D://mysql-installer-community-5.6.26.0.msi");
// 上传文件
HttpClientUploadFile.uploadFile("http://localhost:8080/web/UploadFile",
uploadFiles);
}
}
—–分割线—–
原理和web端一样,解析下web端的request报文,解析一下就明白了
上传代码
package com.zzu.cameratest;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Created by Coder on 2017/2/21.
*/
public class FileUpload {
// 换行符
private static final String newLine = "\r\n";
private static final String boundaryPrefix = "--";
// 定义数据分隔线
private static final String BOUNDARY = "----7d4a6d158c9";
private final static boolean isExited = false;
public static void uploadFile(String urlStr, String filePath) {
//获取文件名
String fileName = filePath.substring(filePath.lastIndexOf('/')+1);
File file = new File(filePath);
//如果要上传的文件不存在
if(!file.exists()){
return;
}
DataOutputStream out = null;
DataInputStream in = null;
BufferedReader reader = null;
try {
// 服务器的域名
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置为POST请求
conn.setRequestMethod("POST");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求头参数
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("Charsert", "UTF-8");
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
out = new DataOutputStream(conn.getOutputStream());
// 上传文件
StringBuilder sb = new StringBuilder();
sb.append(boundaryPrefix);
sb.append(BOUNDARY);
sb.append(newLine);
// 文件参数,photo参数名可以随意修改
sb.append("Content-Disposition: form-data;name=\"photo\";filename=\"" + filePath
+ "\"" + newLine);
sb.append("Content-Type:application/octet-stream");
// 参数头设置完以后需要两个换行,然后才是参数内容
sb.append(newLine);
sb.append(newLine);
// 将参数头的数据写入到输出流中
out.writeBytes(sb.toString());
// 数据输入流,用于读取文件数据
in = new DataInputStream(new FileInputStream(
file));
byte[] bufferOut = new byte[1024 * 4];
int len = -1;
// 每次读4KB数据,并且将文件数据写入到输出流中
while ((len = in.read(bufferOut)) != -1) {
out.write(bufferOut, 0, len);
System.out.println("uploading!!!!!!!");
}
// 最后添加换行
out.writeBytes(newLine);
// 定义最后数据分隔线,即--加上BOUNDARY再加上-- 写上结尾标识
out.writeBytes(newLine + boundaryPrefix + BOUNDARY + boundaryPrefix + newLine);
out.flush();
System.out.println("成功!!!!!!!");
// 定义BufferedReader输入流来读取URL的响应
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();
}finally {
try {
if(in != null){
in.close();
}
if(out != null){
out.close();
}
if(reader != null){
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package servlet;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadFile extends HttpServlet {
private String uploadDir = "D://temp";
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
getHeadersInfo(request);
System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!");
try {
ServletFileUpload upload = new ServletFileUpload();
// set max file size to 100 MB:
upload.setFileSizeMax(100 * 1024 * 1024);
FileItemIterator it = upload.getItemIterator(request);
// handle with each file:
while (it.hasNext()) {
FileItemStream item = it.next();
if (! item.isFormField()) {
// it is a file upload:
handleFileItem(item);
}
}
}
catch(FileUploadException e) {
throw new ServletException("Cannot upload file.", e);
}
}
void handleFileItem(FileItemStream item) throws IOException {
System.out.println("upload file: " + item.getName());
String fileType = item.getName().substring(item.getName().lastIndexOf('.')+1);
File path = new File(uploadDir);
if(!path.exists()){
path.mkdir();
}
File newUploadFile = new File(uploadDir + "/" + UUID.randomUUID().toString()+"."+fileType);
byte[] buffer = new byte[4 * 1024];
InputStream input = null;
BufferedOutputStream output = null;
try {
input = item.openStream();
output = new BufferedOutputStream(new FileOutputStream(newUploadFile));
int len = -1;
while((len = input.read(buffer)) != -1) {
output.write(buffer, 0, len);
}
}
finally {
if (input!=null) {
try {
input.close();
}
catch (IOException e) {}
}
if (output!=null) {
try {
output.close();
}
catch (IOException e) {}
}
}
}
private Map<String, String> getHeadersInfo(HttpServletRequest request) {
Map<String, String> map = new HashMap<String, String>();
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String key = (String) headerNames.nextElement();
String value = request.getHeader(key);
map.put(key, value);
System.out.println(key+" "+value);
}
return map;
}
}