Java编码及网络传输中的编码问题

发表于:2012-1-17 09:22

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:cherishLC    来源:51Testing软件测试网采编

  近来试着FTP搜索,遇到编码问题,研究了下。

  Java内部的String为Unicode编码,每个字符占两个字节。

  Java编解码方法如下:

  1. String str = "hi好啊me";  
  2. byte[] gbkBytes=str.getBytes("GBK");//将String的Unicode编码转为GBK编码,输出到字节中 
  3. String string=new String(gbkBytes,"GBK");//gbkBytes中的字节流以GBK方案解码成Unicode形式的Java字符串

  1、表单数据的编码

  现在的问题是,在网络中,不知道客户端发过来的字节流的编码方案(发送前浏览器会对数据编码!!!各个浏览器还不一样!!!)

  解决方案如下:

  当然URLEncoder.encode(str, "utf-8")和URLDecoder.decode(strReceive,"utf-8")方法中的编码方案要一致。

  2、网址的编码

  但以上方法只适合表单数据的提交;对于URL则不行!!!原因是URLEncoder把'/'也编码了,浏览器发送时报错!!!那么,只要http://IP/子目录把http://IP/这部分原封不动(当然这部分不要有中文),之后的数据以'/'分割后分段编码即可。

  代码如下:

  1. /** 
  2.  * 对{@link URLEncoder#encode(String, String)}的封装,但不编码'/'字符,对其他字符分段编码 
  3.  *  
  4.  * @param str 
  5.  *            要编码的URL 
  6.  * @param encoding 
  7.  *            编码格式 
  8.  * @return 字符串以字符'/'隔开,对每一段单独编码以encoding编码格式编码 
  9.  * @version: 2012_01_10 
  10.  *           <p> 
  11.  *           注意:未考虑':',如直接对http://编解码,会产生错误!!!请在使用前将其分离出来,可以使用 
  12.  *           {@link #encodeURLAfterHost(String, String)}方法解决此问题 
  13.  *           <p> 
  14.  *           注意:对字符/一起编码,导致URL请求异常!! 
  15.  */ 
  16. public static String encodeURL(String str, String encoding) {  
  17.     final char splitter = '/';  
  18.     try {  
  19.         StringBuilder sb = new StringBuilder(2 * str.length());  
  20.         int start = 0;  
  21.         for (int i = 0; i < str.length(); i++) {  
  22.             if (str.charAt(i) == splitter) {  
  23.                 sb.append(URLEncoder.encode(str.substring(start, i),  
  24.                         encoding));  
  25.                 sb.append(splitter);  
  26.                 start = i + 1;  
  27.             }  
  28.         }  
  29.         if (start < str.length())  
  30.             sb.append(URLEncoder.encode(str.substring(start), encoding));  
  31.         return sb.toString();  
  32.     } catch (UnsupportedEncodingException e) {  
  33.         e.printStackTrace();  
  34.     }  
  35.     return null;  
  36. }  
  37. /** 
  38.  * 对IP地址后的URL通过'/'分割后进行分段编码. 
  39.  * <p> 
  40.  * 对{@link URLEncoder#encode(String, String)} 
  41.  * 的封装,但不编码'/'字符,也不编码网站部分(如ftp://a.b.c.d/部分,检测方法为对三个'/'字符的检测,且要求前两个连续), 
  42.  * 对其他字符分段编码 
  43.  *  
  44.  * @param str 
  45.  *            要编码的URL 
  46.  * @param encoding 
  47.  *            编码格式 
  48.  * @return IP地址后字符串以字符'/'隔开,对每一段单独编码以encoding编码格式编码,其他部分不变 
  49.  * @version: 2012_01_10 
  50.  *           <p> 
  51.  *           注意:对字符/一起编码,导致URL请求异常!! 
  52.  */ 
  53. public static String encodeURLAfterHost(String str, String encoding) {  
  54.     final char splitter = '/';  
  55.     int index = str.indexOf(splitter);//第一个'/'的位置 
  56.     index++;//移到下一位置!! 
  57.     if (index < str.length() && str.charAt(index) == splitter) {//检测第一个'/'之后是否还是'/',如ftp:// 
  58.         index++;//从下一个开始 
  59.         index = str.indexOf(splitter, index);//第三个'/';如ftp://anonymous:tmp@g.cn:219.223.168.20/中的最后一个'/' 
  60.         if (index > 0) {  
  61.             return str.substring(0, index + 1)  
  62.                     + encodeURL(str.substring(index + 1), encoding);//如ftp://anonymous:tmp@g.cn:219.223.168.20/天空 
  63.         } else 
  64.             return str;//如ftp://anonymous:tmp@g.cn:219.223.168.20 
  65.     }  
  66.     return encodeURL(str, encoding);  
  67. }  
  68. /** 
  69.  * 对IP地址后的URL通过'/'分割后进行分段编码. 
  70.  * 此方法与{@link #decodeURLAfterHost(String, String)}配对使用 
  71.  * @param str 
  72.  *            要解码的URL 
  73.  * @param encoding 
  74.  *            str的编码格式 
  75.  * @return IP地址后字符串以字符'/'隔开,对每一段单独解码以encoding编码格式解码,其他部分不变 
  76.  * @version: 2012_01_10 
  77.  *  
  78.  *           <p> 
  79.  *           注意:对字符/一起解码,将导致URL请求异常!! 
  80.  */ 
  81. public static String decodeURLAfterHost(String str, String encoding) {  
  82.     final char splitter = '/';  
  83.     int index = str.indexOf(splitter);//第一个'/'的位置 
  84.     index++;//移到下一位置!! 
  85.     if (index < str.length() && str.charAt(index) == splitter) {//检测第一个'/'之后是否还是'/',如ftp:// 
  86.         index++;//从下一个开始 
  87.         index = str.indexOf(splitter, index);//第三个'/';如ftp://anonymous:tmp@g.cn:219.223.168.20/中的最后一个'/' 
  88.         if (index > 0) {  
  89.             return str.substring(0, index + 1)  
  90.                     + decodeURL(str.substring(index + 1), encoding);//如ftp://anonymous:tmp@g.cn:219.223.168.20/天空 
  91.         } else 
  92.             return str;//如ftp://anonymous:tmp@g.cn:219.223.168.20 
  93.     }  
  94.     return decodeURL(str, encoding);  
  95. }  
  96. /** 
  97.  * 此方法与{@link #encodeURL(String, String)}配对使用 
  98.  * <p> 
  99.  * 对{@link URLDecoder#decode(String, String)}的封装,但不解码'/'字符,对其他字符分段解码 
  100.  *  
  101.  * @param str 
  102.  *            要解码的URL 
  103.  * @param encoding 
  104.  *            str的编码格式 
  105.  * @return 字符串以字符'/'隔开,对每一段单独编码以encoding编码格式解码 
  106.  * @version: 2012_01_10 
  107.  *  
  108.  *           <p> 
  109.  *           注意:对字符/一起编码,导致URL请求异常!! 
  110.  */ 
  111. public static String decodeURL(String str, String encoding) {  
  112.     final char splitter = '/';  
  113.     try {  
  114.         StringBuilder sb = new StringBuilder(str.length());  
  115.         int start = 0;  
  116.         for (int i = 0; i < str.length(); i++) {  
  117.             if (str.charAt(i) == splitter) {  
  118.                 sb.append(URLDecoder.decode(str.substring(start, i),  
  119.                         encoding));  
  120.                 sb.append(splitter);  
  121.                 start = i + 1;  
  122.             }  
  123.         }  
  124.         if (start < str.length())  
  125.             sb.append(URLDecoder.decode(str.substring(start), encoding));  
  126.         return sb.toString();  
  127.     } catch (UnsupportedEncodingException e) {  
  128.         e.printStackTrace();  
  129.     }  
  130.     return null;  
  131. }

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号