一、上传工具类FileHelper
import android.os.Handler; import android.os.Message; import android.util.Log; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Iterator; import java.util.Map; import java.util.UUID; /** * Created by Administrator on 2018/3/16. */ public class FileHelper { static String TAG = "FileHelper"; private static final int TIME_OUT = 10 * 1000; // 超时时间 private static final String CHARSET = "utf-8"; // 设置编码 public static final int GET_OK = 1,GET_ERROR = 2; public static CallBack mCallBack; /** * android上传文件到服务器 * * @param form 需要上传的文件 * @return 返回响应的内容 */ public static void uploadFile(final req_multi_form form, final CallBack callBack) { mCallBack = callBack; new Thread(){ @Override public void run() { super.run(); String result = null; String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成 String PREFIX = "--", LINE_END = "\r\n"; String CONTENT_TYPE = "multipart/form-data"; // 内容类型 Map<String, File> files = form.getFileField(); String RequestURL = form.getAction(); Map<String, String> param = form.getNormalField(); try { URL url = new URL(RequestURL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(TIME_OUT); conn.setConnectTimeout(TIME_OUT); conn.setDoInput(true); // 允许输入流 conn.setDoOutput(true); // 允许输出流 conn.setUseCaches(false); // 不允许使用缓存 conn.setRequestMethod("POST"); // 请求方式 conn.setRequestProperty("Charset", CHARSET); // 设置编码 conn.setRequestProperty("connection", "keep-alive"); conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY); if (files != null) { /** * 当文件不为空,把文件包装并且上传 */ DataOutputStream dos = new DataOutputStream( conn.getOutputStream()); StringBuffer sb = new StringBuffer(); String params = ""; if (param != null && param.size() > 0) { Iterator<String> it = param.keySet().iterator(); while (it.hasNext()) { sb = null; sb = new StringBuffer(); String key = it.next(); String value = param.get(key); sb.append(PREFIX).append(BOUNDARY).append(LINE_END); sb.append("Content-Disposition: form-data; name=\"") .append(key).append("\"").append(LINE_END) .append(LINE_END); sb.append(value).append(LINE_END); params = sb.toString(); Log.i(TAG, key + "=" + params + "##"); dos.write(params.getBytes()); // dos.flush(); } } /** * 这里重点注意: name里面的值为服务器端需要key 只有这个key 才可以得到对应的文件 * filename是文件的名字,包含后缀名的 比如:abc.png */ if( files != null && files.size() > 0) { Iterator<String> it = files.keySet().iterator(); while (it.hasNext()) { sb = new StringBuffer(); sb.append(PREFIX); sb.append(BOUNDARY); sb.append(LINE_END); String key = it.next(); File file = files.get(key); //sb.append("Content-Disposition: form-data; name=\"multipartfile["+flag+"]\";filename=\"" + file.getName() + "\"" + LINE_END); sb.append("Content-Disposition: form-data; name=\""+key+"\";filename=\"" + file.getName() + "\"" + LINE_END); if (file.getName().contains("3gp")) { sb.append("Content-Type: video/3gpp; charset=" + CHARSET + LINE_END); }else if (file.getName().contains("mp4")) { sb.append("Content-Type: video/mpeg4; charset=" + CHARSET + LINE_END); }else if (file.getName().contains("amr")) { sb.append("Content-Type: audio/mpeg; charset=" + CHARSET + LINE_END); }else{ sb.append("Content-Type: image/pjpeg; charset=" + CHARSET + LINE_END); } sb.append(LINE_END); dos.write(sb.toString().getBytes()); Log.i(TAG, "files=" + sb.toString() + "##"); InputStream is = new FileInputStream(file); byte[] bytes = new byte[1024]; int len = 0; while ((len = is.read(bytes)) != -1) { dos.write(bytes, 0, len); } is.close(); dos.write(LINE_END.getBytes()); } } byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END) .getBytes(); dos.write(end_data); dos.flush(); /** * 获取响应码 200=成功 当响应成功,获取响应的流 */ int res = conn.getResponseCode(); if (res == 200) { InputStream input = conn.getInputStream(); StringBuffer sb1 = new StringBuffer(); int ss; while ((ss = input.read()) != -1) { sb1.append((char) ss); } result = sb1.toString(); Message msg = new Message(); msg.what = GET_OK; msg.obj = result; handler.sendMessage(msg); } else { handler.sendEmptyMessage(GET_ERROR); } } } catch (MalformedURLException e) { e.printStackTrace(); handler.sendEmptyMessage(GET_ERROR); } catch (IOException e) { e.printStackTrace(); handler.sendEmptyMessage(GET_ERROR); } } }.start(); } public static Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case GET_OK: mCallBack.success((String) msg.obj); break; case GET_ERROR: mCallBack.error(); break; } } }; public interface CallBack{ public void success(String res); public void error(); } }二、参数对象req_multi_form
import java.io.File; import java.util.Map; /** * 多文件表单 * Created by Administrator on 2018/3/17. */ public class req_multi_form { Map<String, File> fileField; Map<String, String> normalField; String action; String method; public Map<String, File> getFileField() { return fileField; } public void setFileField(Map<String, File> fileField) { this.fileField = fileField; } public Map<String, String> getNormalField() { return normalField; } public void setNormalField(Map<String, String> normalField) { this.normalField = normalField; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } }
附:form-data; name设置相同可以在后台用数组接收
http协议例子
Header = {"Content-type" : "multipart/form-data, boundary=AaB03x"} Data = "--AaB03x\r\n" + "content-disposition: form-data; name=\"field1\"\r\n" + "\r\n" + "Joe Blow\r\n" + "--AaB03x\r\n" + "content-disposition: form-data; name="pics"; filename=\"file1.txt\"\r\n" + "Content-Type: text/plain\r\n" + "\r\n" + "...binary contents of file1.txt ...\r\n" + "--AaB03x--\r\n"