解決HttpClient工具中application/x-www-form-urlencoded表單提交時,請求引數中文亂碼問題
阿新 • • 發佈:2019-01-05
一、引數亂碼現象
當我去請求第三方介面時,介面接收格式為Form表單的時候,使用HttpClient工具類。這時,對於封裝進HttpPost物件裡的請求引數,如果有中文引數,會出現亂碼的現象。
二、程式碼現象復現
controller層
@RestController @RequestMapping(value = "/http") public class HttpClientController { @GetMapping(value = "/get") public PrePayResultVO getHttpClientDemo() { String url = "https://xxxx.xxxx.com/xxxx/Xxxxx"; Map map = new HashMap<>(); map.put("cardId", "1234567890"); map.put("carNumber", "粵LX255Q"); map.put("parkCode", "1234567890"); map.put("startTime", "2018-09-18"); map.put("endTime", "2018-10-18"); map.put("defferMoney", "0.01"); JSONObject jsonObject = HttpClientUtils.postForForm(url, map); PrePayResultVO prePayResultVO =JSONObject.parseObject(jsonObject.toString(), PrePayResultVO.class); return prePayResultVO; } }
httpClientUtils
public static JSONObject postForForm(String url, Map<String, String> parms) { HttpPost httpPost = new HttpPost(url); ArrayList<BasicNameValuePair> list = new ArrayList<>(); parms.forEach((key, value) -> list.add(new BasicNameValuePair(key, value))); CloseableHttpClient httpClient = HttpClients.createDefault(); try { if (Objects.nonNull(parms) && parms.size() >0) { httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8")); } InputStream content = httpPost.getEntity().getContent(); InputStreamReader inputStreamReader = new InputStreamReader(content, "UTF-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String readLine = bufferedReader.readLine(); System.out.println("readLine===================================" + readLine); HttpResponse response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); JSONObject jsonObject = JSON.parseObject(EntityUtils.toString(entity, "UTF-8")); return jsonObject; }catch (IOException e) { e.printStackTrace(); }finally { if (Objects.nonNull(httpClient)){ try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; }
列印結果
由此可見,本應列印中的請求引數 “粵LX255Q”,卻變成了 “%E7%B2%A4LX255Q” 這種格式的字串。
三、產生原因
在我們發起請求時,瀏覽器首先會將這些中文字元進行編碼然後再發送給伺服器。實際上,瀏覽器會將它們轉換為 application/x-www-form-urlencoded MIME 字串。
四、解決方法
public static JSONObject postForForm(String url, Map<String, String> parms) { HttpPost httpPost = new HttpPost(url); ArrayList<BasicNameValuePair> list = new ArrayList<>(); parms.forEach((key, value) -> list.add(new BasicNameValuePair(key, value))); CloseableHttpClient httpClient = HttpClients.createDefault(); try { if (Objects.nonNull(parms) && parms.size() >0) { httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8")); } InputStream content = httpPost.getEntity().getContent(); InputStreamReader inputStreamReader = new InputStreamReader(content, "UTF-8"); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String readLine = bufferedReader.readLine(); String s = URLDecoder.decode(readLine, "UTF-8"); System.out.println("readLine===================================" + readLine); System.out.println("s==========================================" + s); HttpResponse response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); JSONObject jsonObject = JSON.parseObject(EntityUtils.toString(entity, "UTF-8")); return jsonObject; }catch (IOException e) { e.printStackTrace(); }finally { if (Objects.nonNull(httpClient)){ try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; }
在獲取請求引數時,再對其使用URLDecoder將application/x-www-form-rulencoded MIME字串轉換為對應編碼的普通字串。
列印結果
五、URLDecoder和URLEncoder的使用總結
-
URLDecoder類包含一個decode(String s,String enc)靜態方法,它可以將application/x-www-form-urlencoded MIME字串轉成普通字串;
-
URLEncoder類包含一個encode(String s,String enc)靜態方法,它可以將普通字串轉換成application/x-www-form-urlencoded MIME字串。
public static void main(String[] args) throws UnsupportedEncodingException {
String name = "千夜";
String decode = URLDecoder.decode("%E5%8D%83%E5%A4%9C", "UTF-8");
System.out.println("application/x-www-form-urlencoded MIME字串轉成普通字串===============" + decode);
String encode = URLEncoder.encode(name, "UTF-8");
System.out.println("普通字串轉換成application/x-www-form-urlencoded MIME字串=============" +encode);
}