HttpClient + SpringMVC 實現多張圖片上傳

客戶端代碼

    /*
	 * @param picPaths 需要上傳的文件路徑集合
	 * 
	 * @param requestURL 請求的url
	 * 
	 * @return 返回響應的內容
	 */
	public static void 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);


			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=\"" + "multipartFiles" + "\"; 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();
			
			if(res == 200) {
			 InputStream is = conn.getInputStream();  
	          int ch;  
	          StringBuffer b = new StringBuffer();  
	          while ((ch = is.read()) != -1) {  
	              b.append((char) ch);  
	          }  
	          String s = b.toString();  
	          
	          
	          System.out.println(s);
			}

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

服務器端

    @RequestMapping(value="imgUploads",method=RequestMethod.POST)
	@ResponseBody
	public Result upload(@RequestParam(required=true)MultipartFile[] multipartFiles,HttpServletRequest request){
		
		ResultData data = new ResultData();
		
		List<Map<String,Object>> images = new ArrayList<Map<String,Object>>();
		
		try {
			
			for(int i = 0; i < multipartFiles.length; i++) {
				MultipartFile multipartFile = multipartFiles[i];
			
				log.info("文件長度: " + multipartFile.getSize());
				log.info("文件類型: " + multipartFile.getContentType());
				log.info("文件名稱: " + multipartFile.getName());
				log.info("文件原名: " + multipartFile.getOriginalFilename());
				
				byte[] bytes = multipartFile.getBytes();
				
				
				String type = FilenameUtils.getExtension(multipartFile.getOriginalFilename());
					
			    ResultMsg msg = upload(bytes, type); //你的服務端上傳代碼
			        
			        //上傳成功,保存Image數據
			    if (msg.isResult()) {
			        	
		        	Map<String,Object> dataMap = new HashMap<String,Object>();
		        	
		        	dataMap.put("filePath", msg.getMsg());//原圖url
					
					//擴展文件信息,可選(如需使用可以客戶端獲取)
		        	dataMap.put("size", multipartFile.getSize());
		        	dataMap.put("contentType", multipartFile.getContentType());
		        	dataMap.put("originalFilename", multipartFile.getOriginalFilename());
		        	
		        	images.add(dataMap);
				}
				
				
			}
			
		} catch (Exception e) {
			log.error("批量上傳圖片失敗:" + e.getMessage(),e.getMessage());
		}
		
		data.put("msg", "圖片上傳成功!");
		
		data.put("results", images);
		
		return new Result(data);
	}

調用示例

	@Test
	public void testUpload() {
		
		String[] uploadFiles =  {"C:\\Users\\wang-lei\\Desktop\\image\\1.png",
		                         "C:\\Users\\wang-lei\\Desktop\\image\\150_75_1.png",
		                         "C:\\Users\\wang-lei\\Desktop\\image\\280_500.png"};

		String requestURL = "http://api.local.net/api/common/upload/imgUploads.json";
		
		UploadImagesTestCase2.uploadFile(uploadFiles, requestURL);
		
		
	}
	

返回數據示例

{
  "code": 0,
  "message": "成功",
  "serverTime": 1471402446400,
  "data": {
    "subCode": 0,
    "subMessage": null,
    "results": [
      {
        "filePath": "0fb619de-3816-4b9c-ace6-1c6508795d5d.png",
        "originalFilename": "1.png",
        "contentType": "image/png",
        "size": 249635
      },
      {
        "filePath": "6fcb3131-8901-41ac-87f9-5fa9f453a7f6.png",
        "originalFilename": "150_75_1.png",
        "contentType": "image/png",
        "size": 17747
      },
      {
        "filePath": "a18819c8-fc93-40d8-bbde-72111a5c872b.png",
        "originalFilename": "280_500.png",
        "contentType": "image/png",
        "size": 201269
      }
    ],
    "msg": "圖片上傳成功!"
  }
}

總結

衆所周知瀏覽器上傳圖片時一般都是一個Form表單中要使用<input type='file' name='file' />來選擇上傳的文件,並上傳,代碼如下:

<html>
    <head>
        <title>upload</title>
        <meta http-equiv="description" content="this is my page">
        <meta http-equiv="content-type" content="text/html; charset=GB18030">
    </head>

    <body>
        <form action="servlet/UploadFile" method="post"
            enctype="multipart/form-data">
            <input type="file" name="file1" id="file1" />
            <input type="file" name="file2" id="file2" />
            <input type="submit" value="上傳" />
        </form>
    </body>
</html>

從上面的代碼可以看出,有兩個文件選擇框(file1和file2),在上傳文件時,<form>標籤必須加上enctype="multipart/form-data",否則瀏覽器無法將文件內容上傳到服務端。

到底這個post請求向服務端發送了什麼信息?從瀏覽器中可以看到以下請求信息:

image

有了這些信息就可以使用HttpClient 拼接好請求串來模擬瀏覽器上傳圖片文件到服務器了,剩下的工作就是接收這些圖片的字節流處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章