一:服务端解析客户端
在服务端解析客户端的编码设置(即服务器接收浏览器发送的数据),采用GB18030的方式,但是这样有一点不好,如果我有1000个页面(.jsp)需要设置需要重复写这样的语句1000条,重复工作,针对此问题的解决,下面给出了解决方案
二:客户端解析服务端
客户端解析服务端返回的数据的编码方式(即浏览器呈现的页面的编码方式),如果一个.html 想改为.jsp,必须添加此句
三:Filter设置编码
public class CharsetEncodingFilter implements Filter {
private String encoding="";
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
//设置字符集,拦截request请求
request.setCharacterEncoding(this.encoding);
//继续往下执行,这体现了职责链模式
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//初始化时,通过参数读取filter的配置文件的value值,即读取设置的编码方式
this.encoding = filterConfig.getInitParameter("encoding");
}
}
需要注意的几点:
Filter是在tomcat启动时new的,生命是由tomcat控制的
Filter只对Post请求起作用
Filter其实是对Request和Response请求进行了拦截
Filter可看作是一种横切性的技术,面向切面的变成
Filter体现了“职责链模式”
实现Filter需要实现javax.servlet.Filter接口,还要在web.xml文件中进行配置
Filter提供了一种声明式服务,声明式服务非常强大,具有可插拔能力
声明式服务
只需要声明在哪里where做什么what,而不需关心如何实现how(体现为要在web.xml声明对哪个文件wher设置那种编码what,具体怎么实现写在了filter类中)
编程式服务
需要以具体的代码表达在哪里where做什么what,如何实现how
配置文件web.xml设置如下:
CharsetEncodingFilter
com.bjpowernode.drp.util.filter.CharsetEncodingFilter
encoding
GBK
*.jsp
如果想对别的文件也起作用:再添一个映射即可
CharsetEncodingFilter
/servlet/*
匹配文件的一种写法:
精准匹配 写完整的路径
扩展匹配,有星号*和扩展名组成,如*.jsp
路径前缀匹配,包含一个目录和一个/*,如/servlet/*,但不能写/servlet/*.jsp
全部匹配,一般使用/*
执行过程:
这样不用在每个.jsp中设置了,每次在请求服务端时,都会先走Filter,设置一下编码
四:Get提交中文乱码
上面提到,Filter只对Post提交起作用,那么当Get提交时,怎么设置那,难道只能每个.jsp都要写一遍吗,当然不是,
Get提交可以考虑改变服务器的配置,如Tomcat需要修改conf下的server.xml文件,如:
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="GB18030"/>
对中文采用java.net.URLEncoder.encode()进行编码,如重定向时URL中有中文:
response.sendRedirect(request.getContextPath() + "/item_maint.jsp?errorMessage=" + URLEncoder.encode(errorMessage,"GB18030"));