问题描述:


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();
        }
    }

如有错误之处,请多多指教,欢迎大家一起交流,共同进步~