通过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# 代码
- static unsigned char hexchars[] = "0123456789ABCDEF";
-
- char *urlencode(char *s)
- {
- register int x, y;
- unsigned char *str;
- int len=strlen(s);
-
- str = (unsigned char *) malloc(3 * strlen(s) + 1);
- for (x = 0, y = 0; len--; x++, y++) {
- str[y] = (unsigned char) s[x];
- if (str[y] == ' ') {
- str[y] = '+';
- #ifndef CHARSET_EBCDIC
- } else if ((str[y] < '0' && str[y] != '-' && str[y] != '.') ||
- (str[y] < 'A' && str[y] > '9') ||
- (str[y] > 'Z' && str[y] < 'a' && str[y] != '_') ||
- (str[y] > 'z')) {
- str[y++] = '%';
- str[y++] = hexchars[(unsigned char) s[x] >> 4];
- str[y] = hexchars[(unsigned char) s[x] & 15];
- }
- #else /*CHARSET_EBCDIC*/
- } else if (!isalnum(str[y]) && strchr("_-.", str[y]) == NULL) {
-
- str[y++] = '%';
- str[y++] = hexchars[os_toascii[(unsigned char) s[x]] >> 4];
- str[y] = hexchars[os_toascii[(unsigned char) s[x]] & 0x0F];
- }
- #endif /*CHARSET_EBCDIC*/
- }
-
-
- str[y] = '\0';
- return ((char *) str);
- }
将ajp_marshal_into_msgb函数体发送属性部分进行修改,修改后的代码为:
cpp 代码
- if (s->num_attributes > 0) {
- for (i = 0; i < s->num_attributes; i++) {
-
- char * pval=s->attributes_values[i];
- char * url=NULL;
- if(strcmp(s->attributes_names[i],"REDIRECT_URL")==0){
- url=urlencode(s->attributes_values[i]);
-
- }
- if (jk_b_append_byte(msg, SC_A_REQ_ATTRIBUTE) ||
- jk_b_append_string(msg, s->attributes_names[i]) ||
- jk_b_append_string(msg, pval)) {
- jk_log(l, JK_LOG_ERROR,
- "failed appending attribute %s=%s",
- s->attributes_names[i], pval);
- JK_TRACE_EXIT(l);
- return JK_FALSE;
- }
- if(url!=NULL) free(url);
- }
- }
最后,在jsp中对REDIRECT_URL进行解码
String url=URLDecoder.decode((String)request.getAttribute("REDIRECT_URL"),"utf-8");
编译,启动tomcat,重新请求不存在的页面http://localhost/rp/数字故宫/hh.html,返回结果为:/rp/æ°åæ
宫/hh.html
看到了了正确的结果:/rp/数字故宫/hh.html
分享到:
相关推荐
1.2.6.dll"和"Isapi_redirect-1.2.14.dll"是两个版本不同的ISAPI(Internet Server Application Programming Interface)重定向器组件,主要用于在IIS(Internet Information Services)服务器上实现对Apache Tomcat...
### IIS6与Tomcat5整合配置流程详解 #### 历史背景 本文档创建于2003年12月23日,并在同年12月24日进行了更新,增加了关于JK2 Connector自动安装程序的先决条件以及IIS6与IIS5隔离模式之间的讨论。 #### 引言 ...
下载并安装Tomcat 5.0,确保将其安装到一个无空格和特殊字符的路径下,例如"C:\Tomcat5"。安装完成后,启动Tomcat服务,并检查默认的8080端口是否能够正常访问Tomcat的管理页面。 其次,准备IIS6的整合。在IIS管理...
- **Tomcat6**:Apache Tomcat 6是一款开源的Java Servlet容器,主要用于部署和运行基于Java的应用程序,尤其是JSP和Servlet。 #### 实现目标 本项目的主要目标是在Windows XP SP3操作系统上配置IIS5以支持JSP应用...
2. **PATH配置**:为了确保系统能够识别这两个软件的位置,还需要将`TOMCAT_HOME`和`JAVA_HOME`的路径添加到系统的`PATH`环境变量中。 3. **启动脚本执行**:开启一个命令行窗口,执行位于`tomcat\bin`目录下的`...