问题描述:
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();
}
}
如有错误之处,请多多指教,欢迎大家一起交流,共同进步~