基于Http的客户端上传 java SE 、 Android 通用
首先必须明确上传需要注意的几个事情
1、请求必须为post请求
2、提交编码需要为multipart/form-data;
一、在web中,比较简单
上传
如果上传不了注意
1、method设置为post,因为默认是get,必须手动设置为post。
2、注意enctype必须为multipart/form-data,意思是表单将以二进制上传
3、此处的name="files" 就是服务端的Action中的files属性名
二、服务端的写法,是基于struts2写的适用于多文件上传,单文件也可以
class UploadAction extends ActionSupport{
private File[] files;
@Override
public String execute() throws Expection{
int i = 0;
for(File file : files){
//获取项目文件目录
String data = ServletActionContext.getServletContext().getRealPath("/data");
//构建存储处
File fi = new File(data+"/"+(i++)+".txt");
//文件路径
Path source = Paths.get(file.getPath());
//把缓存区的文件复制到存储处
Files.copy(source, new FileOutputStream(fi));
}
return super.execute();
}
public void setFile(File[] file) {
this.files = file;
}
}
这里一定要注意的是,如果你是在eclipse中部署服务器并上传的文件,则上传的文件并非在eclipse中的项目的WebContent目录下,他会存到项目缓存区,比如我的项目存到了
~\workSpace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\文件上传\data
三、接下来是是客户端的写法
1.首先来明确一下web端上传究竟上传了些什么,在此我上传了两个txt文件,内容分别是
1.txt:
我是1
2.txt:
我是2
利用http拦截软件得到了如下的信息
POST http://127.0.0.1/wjsc/upload.action HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Referer: http://127.0.0.1/wjsc/index.action
Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,ja;q=0.6,en-US;q=0.4,en;q=0.2
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Content-Type: multipart/form-data; boundary=---------------------------7df258a3609da
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Content-Length: 330
DNT: 1
Host: 127.0.0.1
Pragma: no-cache
-----------------------------7df258a3609da
Content-Disposition: form-data; name="file"; filename="1.txt"
Content-Type: text/plain
我是1
-----------------------------7df3962f3609da
Content-Disposition: form-data; name="file"; filename="2.txt"
Content-Type: text/plain
我是2
-----------------------------7df3962f3609da--
这就是使用网页提交时候提交的内容,所以我们要模仿他:
在java中使用模仿http请求即可
public void upload(List files){
String result = "上传失败";
try {
//生成一个uuid来充当随机数
String boundary = java.util.UUID.randomUUID().toString();
String prefix = "--";
String linend = "\r\n";
String multipart = "multipart/form-data";
String charset = "UTF-8";
URL url = new URL("http://127.0.0.1/wjsc/upload.action");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(5*1000);
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestMethod("POST");
con.setRequestProperty("connection", "Keep-Alive");
con.setRequestProperty("charsert", "UTF-8");
con.setRequestProperty("content-Type", multipart+";boundary=" + boundary);
con.connect();
/*--这里是模拟上传真正的文件前的字符串,总共四行--*/
//-----------------------------7df258a3609da
//*注:这里两个 -- 就可以了7df258a3609da为随机数,这里用生成的UUID来充当
String one = "--" + boundary + linend;
//Content-Disposition: form-data; name="file"; filename="1.txt"
//*注:
//1、这里的"file"就是Action中的属性名,
//2、name="file"; filename="1.txt" 必须是双引号,不能用单引号,所以需要借助 \" 在java字符串中表示双引号。
String two = "Content-Disposition: form-data; name=\"file\"; filename=\"1.txt\""+ linend;
//Content-Type: text/plain
//*注这里的text/plain就是上传的文件类型,
//如果是jpg图片则为 image/jpg png图片为 image/png 这里因为上传的txt文件,所以为text/plain
String three = "Content-Type: text/plain"+linend;
// *注:这是一个空行,必须存在
String four = linend;
//把以上的字符串链接起来
StringBuilder sb = new StringBuilder();
sb.append(one);
sb.append(two);
sb.append(three);
sb.append(four);
String start = sb.toString();
//数据输出流,用于把文件或者字符串的二进制输出到网络上
DataOutputStream dataOut = new DataOutputStream(
con.getOutputStream());
/*---------------------------------------开始上传---------------------------------------*/
for(File file : files){
// 输出文件头
dataOut.write(start.getBytes());
// 输出文件
InputStream is = new FileInputStream(file);
int buffLength = 1024;
byte[] buff = new byte[buffLength];
int len = 0;
while ((len = is.read(buff)) != -1) {
dataOut.write(buff, 0, len);
}
is.close();
dataOut.write(linend.getBytes());
}
// 结束的换行标志
String overFlag = linend+"--" + boundary + "--"+linend;
dataOut.write(overFlag.getBytes());
/*--------------------------------------上传结束--------------------------------------*/
/*--一下是读取服务器返回的信息,与上传无关--*/
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String temp = "";
while((temp = reader.readLine())!=null){
result = temp + result +"\n";
}
result = result + con.getResponseCode();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}