http請求資料包含特殊字元處理(java)
阿新 • • 發佈:2019-02-09
問題描述:
android客戶端與後臺進行網路請求的時候,為了安全起見,我們採用的方法一般是加簽名,這個簽名可以是Base64加密過的,或是RSA加密過的,這些簽名的共同特點就是一大長串字串,裡面包含的有各種字元,比如 +,/n,?,/,$,&
等等,如果這些字元不做特殊處理的話,你很可能得到不正確的結果。
解決辦法:
Get請求:
當我們把請求引數按格式(key=value&key=value)拼接到url後,對結果進行Encode:
URLEncoder.encode(url,"UTF-8")
即可,這樣可以防止特殊字元被轉義成其他字元。
POST請求:
post請求不像get請求,在url進行拼接引數,需要在body中新增請求引數,除了像Get請求一樣對url Encode之外,對於不同的請求體,我們需要新增不同的“Content-Type”,與之對應,這樣伺服器才能正確地解析我們的請求體。Content-Type對照:
- application/x-www-form-urlencoded : 是常用的表單發包方式,普通的表單提交
- multipart/form-data: 當我們上傳檔案時,需要選擇改種type
- application/json : 當我們的請求引數以json格式傳給後臺時,需要選擇該種type
另外,附一個android中,使用HttpUrlConnection請問網路的例項程式碼:
(注意:這段程式碼不能執行,是我在實際專案中的測試程式碼,意思是讓大家看一下HttpURLConnection請問網路的步驟)
public void testHttp() {
/*---------------準備網路請求的引數 start-----------------*/
String s = ThreeDes.decryptThreeDESECB(clientKey);
RSAPrivateKey rsaPrivateKey = RSAUtil.getPrivateKey (s);
TreeMap<String, Object> map = HttpUtil.getMap();
map.put("deviceType", "Android");
map.put("version", "1.8.3");
map.put("deviceNo", "000000000000000");
map.put("clientTime", String.valueOf(System.currentTimeMillis()));
JSONObject jsonObject = new JSONObject(map);
String sign = RSAUtil.sign(jsonObject.toJSONString(), rsaPrivateKey);
/*---------------準備網路請求的引數 end-----------------*/
try {
/*---------------網路請求 start------------------*/
//建立一個URL物件
URL url = new URL("your http url");
//通過url物件的方法,建立網路連線,獲取HttpURLConnection物件例項
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//設定網路請求方式post
conn.setRequestMethod("POST");
//設定網路請求超時時間 10秒
conn.setReadTimeout(10*1000);
//設定可讀寫操作
conn.setDoInput(true);
conn.setDoOutput(true);
//使用 key=value的方式拼接引數
StringBuilder builder = new StringBuilder();
Set<Map.Entry<String, Object>> entries = map.entrySet();
for (Map.Entry<String,Object> entry:
entries) {
String param = entry.getKey() + "=" + entry.getValue().toString() + "&";
builder.append(param);
}
builder.append("sign");
builder.append("=");
//這裡是我出錯的地方,因為sign裡面含有很多特殊字元,如果不encode,會被伺服器轉義成空格等
builder.append(URLEncoder.encode(sign,"UTF-8"));
//將我們拼接好的引數,寫入conn的流中,傳給伺服器
PrintWriter pw = new PrintWriter(conn.getOutputStream());
String str = builder.toString();
char[] chars = str.toCharArray();
String s1 = String.valueOf(chars);
pw.write(str);
pw.flush();
//獲取伺服器返回的資料
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len;
byte[] arr = new byte[1024];
while((len=bis.read(arr))!= -1){
bos.write(arr,0,len);
bos.flush();
}
bos.close();
Log.d(tag,"返回結果:"+bos.toString("utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
}