在做搜索开发过程中,由于翻页功能需要,要把当前查询的中文条件放在URL中带到服务器进行下一页查询,结果出现乱码情况。
此时情况有如下两种:
1、在输入框输入搜索内容,直接通过from提交,参数值正常读到,没有乱码。
2、把中文参数UTF-8编码后,添加到URL后,然后服务器读取到乱码。
服务端使用Spring框架MVC模型处理WEB请求,web.xml配置如下:
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping>
刚刚开始时,以为是过滤器的问题,通过查询后发现,原来CharacterEncodingFilter只有会对POST的数据有效。
spring的CharacterEncodingFilter的过滤机制,该过滤器的源码:
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) { request.setCharacterEncoding(this.encoding);
//这行代码决定了过滤器的过滤机制,这行代码只会对请求正文进行编码,这对于POST方式的请求有效;
//当请求方式为GET时,需要的参数位于请求头的URI中,不会受到该行代码影响。
//所以,spring的CharacterEncodingFilter对于GET方式的HTTP请求,无能为力。
if (this.forceEncoding && responseSetCharacterEncodingAvailable) {
response.setCharacterEncoding(this.encoding);
}
}
filterChain.doFilter(request, response);
}
既然spring的CharacterEncodingFilter对GET方式的HTTP请求无影响,那继续查找其它原因。
当我们通过浏览器提交数据到Tomcat服务器时,首先接触数据的当然是服务器本身啦,然后找到原因了,修改tomcat的配置文件:conf/server.xml 找到connector节点,修改如下:添加URIEncoding="UTF-8"
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8"/>
如果是通过https进行加密访问时,URIEncoding="UTF-8"同样适用
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" keystoreFile="tomcat.keystore" keystorePass="123456" clientAuth="false" sslProtocol="TLS" URIEncoding="UTF-8"/>