原文:http://blog.youkuaiyun.com/skyer_lei/article/details/6106709
本文要用java.net.HttpURLConnection来实现多个文件上传
1. 研究 form 表单到底封装了什么样的信息发送到servlet。
假如我参数写的内容是hello word,然后二个文件是二个简单的txt文件,form提交的信息为:
- -----------------------------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来实现上传文件功能了
- private void upload(String[] uploadFiles, String actionUrl) {
- String end = "/r/n";
- String twoHyphens = "--";
- String boundary = "*****";
- try {
- URL url = new URL(actionUrl);
- HttpURLConnection con = (HttpURLConnection) url.openConnection();
- // 发送POST请求必须设置如下两行
- con.setDoInput(true);
- con.setDoOutput(true);
- con.setUseCaches(false);
- con.setRequestMethod("POST");
- con.setRequestProperty("Connection", "Keep-Alive");
- con.setRequestProperty("Charset", "UTF-8");
- con.setRequestProperty("Content-Type",
- "multipart/form-data;boundary=" + boundary);
- DataOutputStream ds =
- new DataOutputStream(con.getOutputStream());
- for (int i = 0; i < uploadFiles.length; i++) {
- String uploadFile = uploadFiles[i];
- String filename = uploadFile.substring(uploadFile.lastIndexOf("//") + 1);
- ds.writeBytes(twoHyphens + boundary + end);
- ds.writeBytes("Content-Disposition: form-data; " +
- "name=/"file" + i + "/";filename=/"" +
- filename + "/"" + end);
- ds.writeBytes(end);
- FileInputStream fStream = new FileInputStream(uploadFile);
- int bufferSize = 1024;
- byte[] buffer = new byte[bufferSize];
- int length = -1;
- while ((length = fStream.read(buffer)) != -1) {
- ds.write(buffer, 0, length);
- }
- ds.writeBytes(end);
- /* close streams */
- fStream.close();
- }
- ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
- ds.flush();
- // 定义BufferedReader输入流来读取URL的响应
- InputStream is = con.getInputStream();
- int ch;
- StringBuffer b = new StringBuffer();
- while ((ch = is.read()) != -1) {
- b.append((char) ch);
- }
- String s = b.toString();
- if (s.contains("successfully")) {
- // for (int i = 1; i < 5; i++) {
- int beginIndex = s.indexOf("url =") + 5;
- int endIndex = s.indexOf("/n", beginIndex);
- String urlStr = s.substring(beginIndex, endIndex).trim();
- System.out.println(urlStr);
- // }
- }
- ds.close();
- } catch (Exception e) {
- }
- }
使用sendPost后台访问ssl时,会有证书拦截,报错,需要在调用sendPost之前调用该方法HttpDecorate.trustAllHttpsCertificates()
package com.zlz.utils;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class HttpDecorate {
public static void main(String[] args) throws Exception {
//调用信任访问的网站,避开ssl验证
trustAllHttpsCertificates();
String url = "https://168.1.5.19:9012/hcps/index.jsp";
String string = HttpRequest.sendPost(url, "");
System.out.println(string);
}
public static HostnameVerifier hv = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
System.out.println("Warning: URL Host: " + urlHostName + " vs. "
+ session.getPeerHost());
return true;
}
};
public static void trustAllHttpsCertificates() throws Exception {
TrustManager[] trustAllCerts = new TrustManager[1];
TrustManager tm = new miTM();
trustAllCerts[0] = tm;
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
static class miTM implements TrustManager, X509TrustManager {
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public boolean isServerTrusted(X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(X509Certificate[] certs) {
return true;
}
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
return;
}
public void checkClientTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
return;
}
}
}