1. 程式人生 > >android 上傳檔案到伺服器段(servlet)

android 上傳檔案到伺服器段(servlet)

客戶端:

private void addMap() {
		params.put("user", "zhangming");
		params.put("user1", "zhangxiao");
		params.put("user2", "xiao");
		files.put("123456.xls", new File("d:/123456.xls"));
		files.put("654321.xls", new File("d:/654321.xls"));
	}

	private void uploadFile2() throws IOException {
		String BOUNDARY = java.util.UUID.randomUUID().toString();
		String PREFIX = "--", LINEND = "\r\n";
		String MULTIPART_FROM_DATA = "multipart/form-data";
		String CHARSET = "UTF-8";

		URL uri = new URL(URI_PATH);
		HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
		conn.setReadTimeout(5 * 1000); // 快取的最長時間
		conn.setDoInput(true);// 允許輸入
		conn.setDoOutput(true);// 允許輸出
		conn.setUseCaches(false); // 不允許使用快取
		conn.setRequestMethod("POST");
		conn.setRequestProperty("connection", "keep-alive");
		conn.setRequestProperty("Charsert", "UTF-8");
		conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA
				+ ";boundary=" + BOUNDARY);

		// 首先組拼文字型別的引數
		StringBuilder sb = new StringBuilder();
		for (Map.Entry<String, String> entry : params.entrySet()) {
			sb.append(PREFIX);
			sb.append(BOUNDARY);
			sb.append(LINEND);
			sb.append("Content-Disposition: form-data; name=\""
					+ entry.getKey() + "\"" + LINEND);
			sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);
			sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
			sb.append(LINEND);
			sb.append(entry.getValue());
			sb.append(LINEND);
		}

		DataOutputStream outStream = new DataOutputStream(
				conn.getOutputStream());
		outStream.write(sb.toString().getBytes());
		InputStream in = null;
		// 傳送檔案資料
		if (files != null) {
			for (Map.Entry<String, File> file : files.entrySet()) {
				StringBuilder sb1 = new StringBuilder();
				sb1.append(PREFIX);
				sb1.append(BOUNDARY);
				sb1.append(LINEND);
				sb1.append("Content-Disposition: form-data; name=\"file\"; filename=\""
						+ file.getKey() + "\"" + LINEND);
				sb1.append("Content-Type: application/octet-stream; charset="
						+ CHARSET + LINEND);
				sb1.append(LINEND);
				outStream.write(sb1.toString().getBytes());

				InputStream is = new FileInputStream(file.getValue());
				byte[] buffer = new byte[1024];
				int len = 0;
				while ((len = is.read(buffer)) != -1) {
					outStream.write(buffer, 0, len);
				}

				is.close();
				outStream.write(LINEND.getBytes());
			}

			// 請求結束標誌
			byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
			outStream.write(end_data);
			outStream.flush();
			// 得到響應碼
			int res = conn.getResponseCode();
			if (res == 200) {
				in = conn.getInputStream();
				int ch;
				StringBuilder sb2 = new StringBuilder();
				while ((ch = in.read()) != -1) {
					sb2.append((char) ch);
				}
			}
			outStream.close();
			conn.disconnect();
		}
		 System.out.println(in.toString());

	}

/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Test test = new Test();
		test.addMap();
		try {
			test.uploadFile2();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


服務前段servlet接受:

private void fileUpload2(HttpServletRequest request,
			HttpServletResponse response) throws IOException, ServletException {
		
		
		request.setCharacterEncoding("utf-8"); // 設定編碼
		PrintWriter out = response.getWriter();

		// 獲得磁碟檔案條目工廠
		DiskFileItemFactory factory = new DiskFileItemFactory();
		// 獲取檔案需要上傳到的路徑
		String path = request.getRealPath("/upload");

		// 如果沒以下兩行設定的話,上傳大的 檔案 會佔用 很多記憶體,
		// 設定暫時存放的 儲存室 , 這個儲存室,可以和 最終儲存檔案 的目錄不同
		/**
		 * 原理 它是先存到 暫時儲存室,然後在真正寫到 對應目錄的硬碟上, 按理來說 當上傳一個檔案時,其實是上傳了兩份,第一個是以 .tem
		 * 格式的 然後再將其真正寫到 對應目錄的硬碟上
		 */
		factory.setRepository(new File(path));
		// 設定 快取的大小,當上傳檔案的容量超過該快取時,直接放到 暫時儲存室
		factory.setSizeThreshold(1024 * 1024);

		// 高水平的API檔案上傳處理
		ServletFileUpload upload = new ServletFileUpload(factory);

		try {
			// 可以上傳多個檔案
			List<FileItem> list = (List<FileItem>) upload.parseRequest(request);

			for (FileItem item : list) {
				// 獲取表單的屬性名字
				String name = item.getFieldName();

				// 如果獲取的 表單資訊是普通的 文字 資訊
				if (item.isFormField()) {
					// 獲取使用者具體輸入的字串 ,名字起得挺好,因為表單提交過來的是 字串型別的
					String value = item.getString();
					
					//中文亂碼這裡的UTF-8 必須與前臺的編碼一致
					System.out.println(new String(value.getBytes("ISO8859_1"),"utf-8"));
					request.setAttribute(name, value);
					//System.out.println();
				}
				// 對傳入的非 簡單的字串進行處理 ,比如說二進位制的 圖片,電影這些
				else {
					/**
					 * 以下三步,主要獲取 上傳檔案的名字
					 */
					// 獲取路徑名
					String value = item.getName();
					// 索引到最後一個反斜槓
					int start = value.lastIndexOf("\\");
					// 擷取 上傳檔案的 字串名字,加1是 去掉反斜槓,
					String filename = value.substring(start + 1);
					System.out.println("檔名:" + filename);
					Date date = new Date();
					filename = date.getTime() + filename;

					request.setAttribute(name, filename);

					// 真正寫到磁碟上
					// 它丟擲的異常 用exception 捕捉

					// item.write( new File(path,filename) );//第三方提供的

					// 手動寫的
					OutputStream outStream = new FileOutputStream(new File(path,
							filename));

					InputStream in = item.getInputStream();

					int length = 0;
					byte[] buf = new byte[1024];

					System.out.println("獲取上傳檔案的總共的容量:" + item.getSize());

					// in.read(buf) 每次讀到的資料存放在 buf 陣列中
					while ((length = in.read(buf)) != -1) {
						// 在 buf 陣列中 取出資料 寫到 (輸出流)磁碟上
						outStream.write(buf, 0, length);

					}

					in.close();
					outStream.close();
				}
			}
			
			out.println("檔案上傳成功!");


		} catch (FileUploadException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block

			// e.printStackTrace();
		}

		request.getRequestDispatcher("filedemo.jsp").forward(request, response);
	}