1. 程式人生 > >[寫著玩]理解multipart/form-data,構造http表單實現android圖片上傳

[寫著玩]理解multipart/form-data,構造http表單實現android圖片上傳

關於multipart/form-data,可參考https://blog.csdn.net/zshake/article/details/77985757

客戶端 

引數解釋,上傳主方法

private void submit() {
		Map<String, Object> params = new HashMap<String, Object>();
		//普通表單,key-value
		params.put("key", "value");
		//圖片表單,支援多檔案上傳,修改引數即可
		FormFile[] files = new FormFile[2];
		files[0] = new FormFile(String filname, byte[] data, String formname, String contentType);
		files[1] = new FormFile(String filname, byte[] data, String formname, String contentType);
		//上傳方法,回撥方法可更新介面
		httpService.postHttpImageRequest(url, params, files, new HttpCallBackListener() {
			
			public void onFinish(String response) {
				
			}
			public void onError(Exception e) {
				
			}
		});
	}

 圖片資料bean

public class FormFile {  
    /* 上傳檔案的資料 */  
    private byte[] data;  
    /* 檔名稱 */  
    private String filname;  
    /* 表單欄位名稱*/  
    private String formname;  
    /* 內容型別 */  
    private String contentType = "application/octet-stream"; //需要查閱相關的資料  
      
    public FormFile(String filname, byte[] data, String formname, String contentType) {  
        this.data = data;  
        this.filname = filname;  
        this.formname = formname;  
        if(contentType!=null) this.contentType = contentType;  
    }  
  
    public byte[] getData() {  
        return data;  
    }  
  
    public void setData(byte[] data) {  
        this.data = data;  
    }  
  
    public String getFilname() {  
        return filname;  
    }  
  
    public void setFilname(String filname) {  
        this.filname = filname;  
    }  
  
    public String getFormname() {  
        return formname;  
    }  
  
    public void setFormname(String formname) {  
        this.formname = formname;  
    }  
  
    public String getContentType() {  
        return contentType;  
    }  
  
    public void setContentType(String contentType) {  
        this.contentType = contentType;  
    }  
      
}

HttpService

public class HttpService {

	public HttpService() {
	}

	public void postHttpImageRequest(final String netWorkAddress,final Map<String, Object> params,final FormFile[] files,
			final HttpCallBackListener listener) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					HttpURLConnection connection = null;
					try {
					String BOUNDARY = "---------7d4a6d158c9"; //資料分隔線  
			        String MULTIPART_FORM_DATA = "multipart/form-data";  
			          
			        URL url = new URL(UrlInterface.UTILS + netWorkAddress);  
			        connection = (HttpURLConnection) url.openConnection();  
			        connection.setDoInput(true);//允許輸入  
			        connection.setDoOutput(true);//允許輸出  
			        connection.setUseCaches(false);//不使用Cache  
			        connection.setRequestMethod("POST");            
			        connection.setRequestProperty("Connection", "Keep-Alive");  
			        connection.setRequestProperty("Charset", "UTF-8");  
			        connection.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);  
			  
			        StringBuilder sb = new StringBuilder();  
			          
			        //上傳的表單引數部分 
			        for (Entry<String, Object> entry : params.entrySet()) {//構建表單欄位內容  
			            sb.append("--");  
			            sb.append(BOUNDARY);  
			            sb.append("\r\n");  
			            sb.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");
			            sb.append(entry.getValue());  
			            sb.append("\r\n");  
			        }  
			        DataOutputStream outStream = new DataOutputStream(connection.getOutputStream());  
			        outStream.write(sb.toString().getBytes());//傳送表單欄位資料  
			         
			        //上傳的檔案部分 
			        for(FormFile file : files){  
			            StringBuilder split = new StringBuilder();  
			            split.append("--");  
			            split.append(BOUNDARY);  
			            split.append("\r\n");  
			            split.append("Content-Disposition: form-data; name=\""+ file.getFormname()+"\"; filename=\""+ file.getFilname() + "\"\r\n");  
			            split.append("Content-Type: "+ file.getContentType()+"\r\n\r\n");  
			            outStream.write(split.toString().getBytes());  
			            outStream.write(file.getData(), 0, file.getData().length);  
			            outStream.write("\r\n".getBytes());  
			        }  
			        byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();//資料結束標誌           
			        outStream.write(end_data);  
			        outStream.flush();  
			        int cah = connection.getResponseCode();  
			        if (cah != 200) throw new RuntimeException("請求url失敗");  
			        InputStream in = connection.getInputStream();
					BufferedReader reader = new BufferedReader(new InputStreamReader(in));
					StringBuilder response = new StringBuilder();
					String line;
					while ((line = reader.readLine()) != null) {
						response.append(line);
					}

					if (listener != null) {
						listener.onFinish(response.toString());
					} 
			        outStream.close();  
			    } catch (Exception e) {
					if (listener != null) {
						listener.onError(e);
					}
				}  finally {
					if (connection != null) {
						connection.disconnect();
					}
				}
			}
		}).start();
	}
	public interface HttpCallBackListener {
		void onFinish(String response);

		void onError(Exception e);
	}
}

服務端 

public class UploadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

  
    // 上傳配置
    private static final int MEMORY_THRESHOLD   = 1024 * 1024 * 3;  // 3MB
    private static final int MAX_FILE_SIZE      = 1024 * 1024 * 40; // 40MB
    private static final int MAX_REQUEST_SIZE   = 1024 * 1024 * 50; // 50MB
	
    /**
     * @see HttpServlet#HttpServlet()
     */
    public UploadServlet() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/json;charset=utf-8");
		// 配置上傳引數
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 設定記憶體臨界值 - 超過後將產生臨時檔案並存儲於臨時目錄中
        factory.setSizeThreshold(MEMORY_THRESHOLD);
        // 設定臨時儲存目錄
        factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
  
        ServletFileUpload upload = new ServletFileUpload(factory);
          
        // 設定最大檔案上傳值
        upload.setFileSizeMax(MAX_FILE_SIZE);
          
        // 設定最大請求值 (包含檔案和表單資料)
        upload.setSizeMax(MAX_REQUEST_SIZE);
        upload.setHeaderEncoding("UTF-8"); 
        // 構造臨時路徑來儲存上傳的檔案
        // 這個路徑相對當前應用的目錄
        String uploadPath = "/usr/image";
          
        // 如果目錄不存在則建立
        File uploadDir = new File(uploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdir();
        }
        JSONObject jsonRes = null;
        String resStr = null;
        try {
        	JSONObject json = new JSONObject();
            // 解析請求的內容提取檔案資料
            List<FileItem> formItems = upload.parseRequest(request);
 
            if (formItems != null && formItems.size() > 0) {
                // 迭代表單資料
                for (FileItem item : formItems) {
                    // 處理不在表單中的欄位
                    if (item.isFormField()) {
                    	json.put(item.getFieldName(), item.getString("UTF-8"));
                    }else{
                    	String fileName = new File(item.getName()).getName();
                        String filePath = uploadPath + File.separator + fileName;
                        File storeFile = new File(filePath);
                        // 儲存檔案到硬碟
                        item.write(storeFile);
                        json.put(item.getFieldName(),fileName);
                    }
                }
            }
            //業務處理
            //
            //
            
            jsonRes = new JSONObject(resStr);
            
            
        } catch (Exception ex) {
        	
        }
        PrintWriter out =response.getWriter();
		out.println(jsonRes.toString());
		out.close();
	}

}