fiddler抓包查清apache的httpclient中文亂碼問題

今天要和第三方公司對接一個服務。通過rest服務傳文件和一些參數過去。難度不大,先用postman調用了一下,順利返回結果。於是開寫,因為比較熟悉apache.httpcomponents的httpclient,寫的也比較順手。所以直接寫了代碼,測試總是失敗。因為服務提供者沒有人員支持,我只能得到一個失敗錯誤,沒有任何有效信息。

一次次檢查自己的代碼,確實沒有什麼問題。眼看著交工的dead line要到了,沒辦法。趕緊把以前的一份用java原生的HttpUrlConnection發送POST請求的代碼拿來改了改,測試成功。

但是心裡覺得太奇怪,沒道理httpclient不好使啊。

我倒要看看他們發出的包到底有什麼不一樣。

使用Fiddler抓包

抓包工具我這邊使用的是fiddler。關於fiddler的基本操作這裡就不講了。

使用postman的請求包:

fiddler抓包查清apache的httpclient中文亂碼問題


fiddler抓包查清apache的httpclient中文亂碼問題

對代碼進行抓包。這裡有點操作需要講講了。

首先看下你的抓包工具監聽的端口是啥,默認是8888.

fiddler抓包查清apache的httpclient中文亂碼問題

然後需要對代碼進行一些改造。fiddler可以方便的抓取瀏覽器,操作系統的http請求,但是我們在代碼裡發出的http,fiddler是抓不到的。需要在代碼裡設置代理。

java HttpUrlConnection的請求包:

設置代理的代碼:

<code>Proxy proxy = new Proxy(java.net.Proxy.Type.HTTP,
     new InetSocketAddress("127.0.0.1", 8888));
URL realUrl = new URL(url);
HttpURLConnection urlConnection = (HttpURLConnection) realUrl.openConnection(proxy);/<code>
fiddler抓包查清apache的httpclient中文亂碼問題

fiddler抓包查清apache的httpclient中文亂碼問題

使用apache commons 的HttpClient

設置代理的代碼:

<code>//設置代理IP、端口、協議(請分別替換)
HttpHost proxy = new HttpHost("127.0.0.1", 8888, "http");

//把代理設置到請求配置
RequestConfig defaultRequestConfig = RequestConfig.custom()
      .setProxy(proxy)
      .build();
CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();/<code>
fiddler抓包查清apache的httpclient中文亂碼問題


fiddler抓包查清apache的httpclient中文亂碼問題

通過抓包,發現了問題的根源原來是中文亂碼。又是編碼問題。

問題解決:

通過自定義一個contentType

<code>ContentType contentType = ContentType.create("text/plain", Charset.forName("UTF-8"));/<code>

然後在addTextBody時,指明使用自定義的這個contentType

<code>builder.addTextBody(entry.getKey(), entry.getValue(), ContentType.TEXT_PLAIN);/<code>

測試,好了

fiddler抓包查清apache的httpclient中文亂碼問題

text/plain和一個ContentType.TEXT_PLAIN很像啊,

改成ContentType.TEXT_PLAIN試試,發現也不行。我們來對比下:

<code>ContentType.create("text/plain", Charset.forName("UTF-8"));/<code>
<code>ContentType TEXT_PLAIN = create("text/plain", Consts.ISO_8859_1);/<code>

最後發現是編碼格式的問題。

一句話,記住:通過httpClient發送form表單中有中文的,要設置編碼格式為ContentType.create("text/plain", Charset.forName("UTF-8"));

具體源碼可查閱公眾號:技術筆記與開源分享


分享到:


相關文章: