日期:2014-05-16  浏览次数:21129 次

Apache2.2和Tomcat5.0的整合(二)—解决REDIRECT_URL的中文路径问题
  • 现象

通过mod_jk整合Apache和Tomcat,在Servlet中可以通过request.getAttribute("REDIRECT_URL")获得Apache自定义错误处理的原始URL。
不幸的是,如果这个REDIRECT_URL包含中文路径,我们获得的将是乱码。
例如:请求不存在的页面http://localhost/rp/数字故宫/hh.html,
返回结果为:/rp/??°?-???????/hh.html
  • 问题定位
问题出在哪里呢?
作以下测试:
在Apache的httpd.conf加入如下两行
JkEnvVar DPM1 %e6%95%b0%e5%ad%97%e6%95%85%e5%ae%ab
JkEnvVar DPM2 数字故宫
结果第一行返回: %e6%95%b0%e5%ad%97%e6%95%85%e5%ae%ab
第二行返回: ??°?-???????
即jk本身不能正确将环境变量的中文值送到request.getAttribute

下载mod_jk源代码http://tomcat.apache.org/download-connectors.cgi
通过代码分析、日志跟踪,确定Apache送到jk的REDIRECT_URL值为utf-8编码
此变量值经过jk_b_append_string函数写入到缓冲后,通过socket8009发送给tomcat之后,
再经过tomcat接收分析之后,出现乱码。
  • 解决办法
解决办法,既然jk处理西文没有问题,何不将中文URL进行URLEnocode
从网上收到urlencode的C实现:
c# 代码
?
  1. static?unsigned?char?hexchars[]?=?"0123456789ABCDEF";??
  2. ??
  3. char?*urlencode(char?*s)??
  4. {??
  5. ????register?int?x,?y;??
  6. ????unsigned?char?*str;??
  7. ????int?len=strlen(s);??
  8. ??
  9. ????str?=?(unsigned?char?*)?malloc(3?*?strlen(s)?+?1);??
  10. ????for?(x?=?0,?y?=?0;?len--;?x++,?y++)?{??
  11. ????????str[y]?=?(unsigned?char)?s[x];??
  12. ????????if?(str[y]?==?'?')?{??
  13. ????????????str[y]?=?'+';??
  14. #ifndef?CHARSET_EBCDIC??
  15. ????????}?else?if?((str[y]?<?'0'?&&?str[y]?!=?'-'?&&?str[y]?!=?'.')?||??
  16. ???????????????????(str[y]?<?'A'?&&?str[y]?>?'9')?||??
  17. ???????????????????(str[y]?>?'Z'?&&?str[y]?<?'a'?&&?str[y]?!=?'_')?||??
  18. ???????????????????(str[y]?>?'z'))?{??
  19. ????????????str[y++]?=?'%';??
  20. ????????????str[y++]?=?hexchars[(unsigned?char)?s[x]?>>?4];??
  21. ????????????str[y]?=?hexchars[(unsigned?char)?s[x]?&?15];??
  22. ????????}??
  23. #else?/*CHARSET_EBCDIC*/??
  24. ????????}?else?if?(!isalnum(str[y])?&&?strchr("_-.",?str[y])?==?NULL)?{??
  25. ????????????/*?Allow?only?alphanumeric?chars?and?'_',?'-',?'.';?escape?the?rest?*/??