1. 程式人生 > >httpclient:與springmvc進行跨域傳輸,上傳檔案,攜帶引數——使用HttpPost方式

httpclient:與springmvc進行跨域傳輸,上傳檔案,攜帶引數——使用HttpPost方式

一.上傳檔案

1.HttpClient類

/**
	 * @param file
	 * @param url
	 */
	public static void uploadFileByHttpPost(File file, String url) {
		CloseableHttpClient client = HttpClients.custom().build();
		try {
			HttpPost post = new HttpPost(url);
			FileBody fileBody = new FileBody(file);
			/*
			 * 可以在MultipartEntityBuilder中新增多個part(ContentBody),用來傳遞多個引數
			 * ByteArrayBody
			 * InputStreamBody
			 * FileBody
			 * StringBody
			 */
			HttpEntity entity = MultipartEntityBuilder.create().addPart("file", fileBody).build();
			post.setEntity(entity);
			CloseableHttpResponse resp = client.execute(post);
			int status = resp.getStatusLine().getStatusCode();
			if (status == 200) {
				Logger.getLogger(HttpClientUtil.class).info("上傳成功");
			} else {
				Logger.getLogger(HttpClientUtil.class).info("上傳失敗");
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

2.controller介面

@RequestMapping(params = "uploadFile")
	public void uploadFile(@RequestParam CommonsMultipartFile file) {
		File serverFile = new File("E:/to/" + file.getOriginalFilename());
		try {
			FileUtils.writeByteArrayToFile(serverFile, file.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

3.測試類

@Test
	public void uploadFileByHttpPost() {
		String url = PropUtil.configProp.getProperty("url") + "/httpClientController.do?uploadFile";
		File file = new File("E:/from/test");
		HttpClientUtil.uploadFileByHttpPost(file, url);
	}

二.上傳檔案並攜帶引數

1.HttpClient類

/**
	 * @param file
	 * @param url
	 * @param params
	 */
	public static void sendFileAndParamsByHttpPost(File file, String url, Map<String, String> params) {
		CloseableHttpClient client = HttpClients.custom().build();
		try {
			HttpPost post = new HttpPost(url);
			FileBody fileBody = new FileBody(file);
			MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
			for (Entry<String, String> entry : params.entrySet()) {
				String key = entry.getKey();
				String value = entry.getValue();
//				multipartEntityBuilder.addTextBody(key, value);
				multipartEntityBuilder.addTextBody(key, value, ContentType.TEXT_PLAIN.withCharset("utf-8"));
			}
			HttpEntity entity = multipartEntityBuilder
					.addPart("file", fileBody)
					.build();
			post.setEntity(entity);
			CloseableHttpResponse resp = client.execute(post);
			int status = resp.getStatusLine().getStatusCode();
			if (status == 200) {
				Logger.getLogger(HttpClientUtil.class).info("上傳成功");
			} else {
				Logger.getLogger(HttpClientUtil.class).info("上傳失敗");
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
注:
multipartEntityBuilder.addTextBody不設定編碼可能會中文亂碼

2.controller介面

@RequestMapping(params = "sendFileAndParamsByHttpPost")
	public void sendFileAndParamsByHttpPost(@RequestParam CommonsMultipartFile file, @RequestParam("userName") String username, @RequestParam String id, String sex) {
		LoggerFactory.getLogger(getClass()).info("fileName: {}, userName: {}, id: {}, sex: {}", file.getOriginalFilename(), username, id, sex);
	}

3.測試類

@Test
	public void sendFileAndParamsByHttpPost() {
		String url = PropUtil.configProp.getProperty("url") + "/httpClientController.do?sendFileAndParamsByHttpPost";
		File file = new File("E:/from/test");
		Map<String, String> params = new HashMap<String, String>(3);
		params.put("sex", "男");
		params.put("id", "007");
		params.put("userName", "張三");
		HttpClientUtil.sendFileAndParamsByHttpPost(file, url, params);
	}

4.測試結果

// [2018-07-14 17:08:46] [INFO]  fileName: test, userName: ??, id: 007, sex: ?
		
// [2018-07-14 17:14:31] [INFO]  fileName: test, userName: 張三, id: 007, sex: 男

第一條結果為未設定編碼的結果

第二條結果未設定編碼後

controller介面注意:

@RequestParam CommonsMultipartFile file, @RequestParam("userName") String username, @RequestParam String id, String sex

若入參名與傳遞來的引數名一致,則可以不加@RequestParam

若入參名與傳遞來的引數名不一致,則需要@RequestParam("傳過來的引數名")

三.傳遞json,使用model接收

1.HttpClient類

/**
	 * 通過post請求以json格式傳送model
	 * @param t
	 * @param url
	 */
	public static <T> void sendDataJsonByPost(T t, String url) {
		ObjectMapper mapper = new ObjectMapper();
		String data = "";
		try {
			data = mapper.writeValueAsString(t);
		} catch (JsonGenerationException e1) {
			e1.printStackTrace();
		} catch (JsonMappingException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		CloseableHttpClient client = HttpClients.custom().build();
		HttpPost post = new HttpPost(url);
		try {
			// 以entity形式攜帶引數
			post.setEntity(new StringEntity(data, "UTF-8"));
			// 設定頭資訊,以josn格式傳送
			post.addHeader("Content-Type", "application/json");
			CloseableHttpResponse resp = client.execute(post);
			if (resp.getStatusLine().getStatusCode() == 200) {
				Logger.getLogger(HttpClientUtil.class).info("傳送成功");
				Logger.getLogger(HttpClientUtil.class).info(EntityUtils.toString(resp.getEntity()));
			} else {
				Logger.getLogger(HttpClientUtil.class).info("傳送失敗");
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			client.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

2.controller

@RequestMapping(params = "sendDataJsonByPost", produces = MediaType.APPLICATION_JSON_VALUE)
	public void sendDataJsonByPost(@RequestBody User user) {
		LoggerFactory.getLogger(getClass()).info(user.toString());
	}

3.測試類

@Test
	public void sendDataJsonByPost() {
		User user = new User("張三", "1"); 
		String url = PropUtil.configProp.getProperty("url") + "/httpClientController.do?sendDataJsonByPost";
		HttpClientUtil.sendDataJsonByPost(user, url);
	}

4.測試結果

[2018-07-14 17:59:48] [INFO]  User [userName=張三, id=1]

四.使用NameValuePair傳遞引數

1.HttpClient類

/**
	 * 以post方式進行請求,得到布林型別值
	 * @param url
	 * @param params
	 * @return
	 */
	public static boolean booleanReturnByPost(String url, List<NameValuePair> params) {
		CloseableHttpClient client = HttpClients.custom().build();
		HttpPost post = new HttpPost(url);
		try {
			post.setEntity(new UrlEncodedFormEntity(params));
			CloseableHttpResponse resp = client.execute(post);
			if (resp.getStatusLine().getStatusCode() == 200) {
				// springmvc 返回值不能是布林型別,所以返回"true" or "false",再進行轉換
				// 使用EntityUtils將resp.getEntity()解析
				if (Boolean.parseBoolean(EntityUtils.toString(resp.getEntity()))) {
					return true;
				}
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			client.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

2.controller

@RequestMapping(params = "booleanReturnByPost")
	public String booleanReturnByPost(String fileName, String userName) {
		LoggerFactory.getLogger(getClass()).info("fileName: {}, userName: {}", fileName, userName);
		if (userName == null) {
			return "true";
		}
		return "false";	
	}

3.測試類

@Test
	public void booleanReturnByPost() {
		Map<String, String> paramsMap = new HashMap<String, String>(2);
		paramsMap.put("fileName", "測試");
		paramsMap.put("username", "張三");
		String url = PropUtil.configProp.getProperty("url") + "/httpClientController.do?booleanReturnByPost";
		System.out.println(HttpClientUtil.booleanReturnByPost(url , paramsMap));
	}

4.測試結果

true

[2018-07-14 18:03:54] [INFO] fileName: 測試, userName: null

userName為null是因為接收引數與傳送引數大小寫不完全一致

五:關於controller介面的說明會在另外關於springmvc的部落格中說明