客戶端一:下面爲 Android 客戶端的實現代碼:html
/** * android上傳文件到服務器 * * 下面爲 http post 報文格式 * POST/logsys/home/uploadIspeedLog!doDefault.html HTTP/1.1 Accept: text/plain, Accept-Language: zh-cn Host: 192.168.24.56 Content-Type:multipart/form-data;boundary=-----------------------------7db372eb000e2 User-Agent: WinHttpClient Content-Length: 3693 Connection: Keep-Alive 注:上面爲報文頭 -------------------------------7db372eb000e2 Content-Disposition: form-data; name="file"; filename="kn.jpg" Content-Type: image/jpeg (此處省略jpeg文件二進制數據...) -------------------------------7db372eb000e2-- * * @param picPaths * 須要上傳的文件路徑集合 * @param requestURL * 請求的url * @return 返回響應的內容 */ public static String uploadFile(String[] picPaths, String requestURL) { String boundary = UUID.randomUUID().toString(); // 邊界標識 隨機生成 String prefix = "--", end = "\r\n"; String content_type = "multipart/form-data"; // 內容類型 String CHARSET = "utf-8"; // 設置編碼 int TIME_OUT = 10 * 10000000; // 超時時間 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", "utf-8"); // 設置編碼 conn.setRequestProperty("connection", "keep-alive"); conn.setRequestProperty("Content-Type", content_type + ";boundary=" + boundary); /** * 當文件不爲空,把文件包裝而且上傳 */ OutputStream outputSteam = conn.getOutputStream(); DataOutputStream dos = new DataOutputStream(outputSteam); StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(prefix); stringBuffer.append(boundary); stringBuffer.append(end); dos.write(stringBuffer.toString().getBytes()); String name = "userName"; dos.writeBytes("Content-Disposition: form-data; name=\"" + name + "\"" + end); dos.writeBytes(end); dos.writeBytes("zhangSan"); dos.writeBytes(end); for(int i = 0; i < picPaths.length; i++){ File file = new File(picPaths[i]); StringBuffer sb = new StringBuffer(); sb.append(prefix); sb.append(boundary); sb.append(end); /** * 這裏重點注意: name裏面的值爲服務器端須要key 只有這個key 才能夠獲得對應的文件 * filename是文件的名字,包含後綴名的 好比:abc.png */ sb.append("Content-Disposition: form-data; name=\"" + i + "\"; filename=\"" + file.getName() + "\"" + end); sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + end); sb.append(end); dos.write(sb.toString().getBytes()); InputStream is = new FileInputStream(file); byte[] bytes = new byte[8192];//8k int len = 0; while ((len = is.read(bytes)) != -1) { dos.write(bytes, 0, len); } is.close(); dos.write(end.getBytes());//一個文件結束標誌 } byte[] end_data = (prefix + boundary + prefix + end).getBytes();//結束 http 流 dos.write(end_data); dos.flush(); /** * 獲取響應碼 200=成功 當響應成功,獲取響應的流 */ int res = conn.getResponseCode(); Log.e("TAG", "response code:" + res); if (res == 200) { return SUCCESS; } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return FAILURE; }
服務端一:下面爲 Java Web 服務端 servlet 的實現代碼:java
public class FileImageUploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; private ServletFileUpload upload; private final long MAXSize = 4194304 * 2L;// 4*2MB private String filedir = null; /** * @see HttpServlet#HttpServlet() */ public FileImageUploadServlet() { super(); // TODO Auto-generated constructor stub } /** * 設置文件上傳的初始化信息 * * @see Servlet#init(ServletConfig) */ public void init(ServletConfig config) throws ServletException { FileItemFactory factory = new DiskFileItemFactory();// Create a factory // for disk-based // file items this.upload = new ServletFileUpload(factory);// Create a new file upload // handler this.upload.setSizeMax(this.MAXSize);// Set overall request size // constraint 4194304 filedir = config.getServletContext().getRealPath("images"); System.out.println("filedir=" + filedir); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ @SuppressWarnings("unchecked") protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub PrintWriter out = response.getWriter(); try { // String userName = request.getParameter("userName");//獲取form // System.out.println(userName); List<FileItem> items = this.upload.parseRequest(request); if (items != null && !items.isEmpty()) { for (FileItem fileItem : items) { String filename = fileItem.getName(); if (filename == null) {// 說明獲取到的可能爲表單數據,爲表單數據時要本身讀取 InputStream formInputStream = fileItem.getInputStream(); BufferedReader formBr = new BufferedReader(new InputStreamReader(formInputStream)); StringBuffer sb = new StringBuffer(); String line = null; while ((line = formBr.readLine()) != null) { sb.append(line); } String userName = sb.toString(); System.out.println("姓名爲:" + userName); continue; } String filepath = filedir + File.separator + filename; System.out.println("文件保存路徑爲:" + filepath); File file = new File(filepath); InputStream inputSteam = fileItem.getInputStream(); BufferedInputStream fis = new BufferedInputStream(inputSteam); FileOutputStream fos = new FileOutputStream(file); int f; while ((f = fis.read()) != -1) { fos.write(f); } fos.flush(); fos.close(); fis.close(); inputSteam.close(); System.out.println("文件:" + filename + "上傳成功!"); } } System.out.println("上傳文件成功!"); out.write("上傳文件成功!"); } catch (FileUploadException e) { e.printStackTrace(); out.write("上傳文件失敗:" + e.getMessage()); } } }
客戶端二:下面爲用 .NET 做爲客戶端實現的 C# 代碼:android
/** 下面爲 http post 報文格式 POST/logsys/home/uploadIspeedLog!doDefault.html HTTP/1.1 Accept: text/plain, Accept-Language: zh-cn Host: 192.168.24.56 Content-Type:multipart/form-data;boundary=-----------------------------7db372eb000e2 User-Agent: WinHttpClient Content-Length: 3693 Connection: Keep-Alive 注:上面爲報文頭 -------------------------------7db372eb000e2 Content-Disposition: form-data; name="file"; filename="kn.jpg" Content-Type: image/jpeg (此處省略jpeg文件二進制數據...) -------------------------------7db372eb000e2-- * * */ private STATUS uploadImages(String uri) { String boundary = "------------Ij5ei4ae0ei4cH2ae0Ef1ei4Ij5gL6";; // 邊界標識 String prefix = "--", end = "\r\n"; /** 根據uri建立WebRequest對象**/ WebRequest httpReq = WebRequest.Create(new Uri(uri)); httpReq.Method = "POST";//方法名 httpReq.Timeout = 10 * 10000000;//超時時間 httpReq.ContentType = "multipart/form-data; boundary=" + boundary;//數據類型 /*******************************/ try { /** 第一個數據爲form,名稱爲par,值爲123 */ StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(prefix); stringBuilder.Append(boundary); stringBuilder.Append(end); String name = "userName"; stringBuilder.Append("Content-Disposition: form-data; name=\"" + name + "\"" + end); stringBuilder.Append(end); stringBuilder.Append("zhangSan"); stringBuilder.Append(end); /*******************************/ Stream steam = httpReq.GetRequestStream();//獲取到請求流 byte[] byte8 = Encoding.UTF8.GetBytes(stringBuilder.ToString());//把form的數據以二進制流的形式寫入 steam.Write(byte8, 0, byte8.Length); /** 列出 G:/images/ 文件夾下的全部文件**/ DirectoryInfo fileFolder = new DirectoryInfo("G:/images/"); FileSystemInfo[] files = fileFolder.GetFileSystemInfos(); for(int i = 0; i < files.Length; i++) { FileInfo file = files[i] as FileInfo; stringBuilder.Clear();//清理 stringBuilder.Append(prefix); stringBuilder.Append(boundary); stringBuilder.Append(end); /** * 這裏重點注意: name裏面的值爲服務器端須要key 只有這個key 才能夠獲得對應的文件 * filename是文件的名字,包含後綴名的 好比:abc.png */ stringBuilder.Append("Content-Disposition: form-data; name=\"" + i + "\"; filename=\"" + file.Name + "\"" + end); stringBuilder.Append("Content-Type: application/octet-stream; charset=utf-8" + end); stringBuilder.Append(end); byte[] byte2 = Encoding.UTF8.GetBytes(stringBuilder.ToString()); steam.Write(byte2, 0, byte2.Length); FileStream fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read);//讀入一個文件。 BinaryReader r = new BinaryReader(fs);//將讀入的文件保存爲二進制文件。 int bufferLength = 8192;//每次上傳8k; byte[] buffer = new byte[bufferLength]; long offset = 0;//已上傳的字節數 int size = r.Read(buffer, 0, bufferLength); while (size > 0) { steam.Write(buffer, 0, size); offset += size; size = r.Read(buffer, 0, bufferLength); } /** 每一個文件結束後有換行 **/ byte[] byteFileEnd = Encoding.UTF8.GetBytes(end); steam.Write(byteFileEnd, 0, byteFileEnd.Length); fs.Close(); r.Close(); } byte[] byte1 = Encoding.UTF8.GetBytes(prefix + boundary + prefix + end);//文件結束標誌 steam.Write(byte1, 0, byte1.Length); steam.Close(); WebResponse response = httpReq.GetResponse();// 獲取響應 Console.WriteLine(((HttpWebResponse)response).StatusDescription);// 顯示狀態 steam = response.GetResponseStream();//獲取從服務器返回的流 StreamReader reader = new StreamReader(steam); string responseFromServer = reader.ReadToEnd();//讀取內容 Console.WriteLine(responseFromServer); // 清理流 reader.Close(); steam.Close(); response.Close(); return STATUS.SUCCESS; } catch (System.Exception e) { Console.WriteLine(e.ToString()); return STATUS.FAILURE; } }
服務端二: 下面爲 .NET 實現的服務端 C# 代碼:c#
protected void Page_Load(object sender, EventArgs e) { string userName = Request.Form["userName"];//接收form HttpFileCollection MyFilecollection = Request.Files;//接收文件 for (int i = 0; i < MyFilecollection.Count; i++ ) { MyFilecollection[i].SaveAs(Server.MapPath("~/netUploadImages/" + MyFilecollection[i].FileName));//保存圖片 } }