在java web中字符编码的处理是一件很繁琐的事情,如果不对编码进行处理,总会出现各种奇怪的字符,甚至如果代码写的不好,还可能引发莫名其妙的错误。所以,想偷懒的人们总会来研究一些能对字符编码进行统一处理的办法,此时,过滤器来担此大任!
本文参考博客:
用过滤器filter设置编码格式
Servlet编码过滤器(Post和get方式都支持)
由于目前国际通用编码为utf-8
,因此本文默认使用该编码对字符进行处理。
下面开始进行讲解原理,已经理解原理的朋友可以直接跳到最下面,复制后可直接当工具类使用。
首先在servlet中,对于字符编码的处理,post和get方式传过来的数据的处理方式是不同的。
对于post方式传来的数据,处理方式很简单,只需要在最前面加上如下一句即可:
request.setCharacterEncoding("utf-8");
注意这一句必须放在获取参数之前,不然参数都获取完了你改request的编码也没用。
然后再get方法中,使用上述语句设置编码是不起作用的,这个时候你只能在获取完参数后,对参数值进行重新编码,才能正常显示。
//假设get方法中,有个参数叫name
String value = request.getParameter("name");
//之后对value进行重新编码
value = new String(value.getBytes("ISO8859-1"),"utf-8");
上面重新编码可能让人头疼了,不知哪里冒出来的ISO8859-1
是什么鬼?
这是因为tomcat默认编码是ISO8859-1,这里这句话的意思就是说将原来获取到的乱码再用ISO8859-1
进行解码,就得到了二进制字符串了,然后这个时候对字符串再使用utf-8
进行编码,这样就能得到正常显示的字符串了。
那么搞清楚了以上,再看代码就很好理解了。在此提醒一句,已经在过滤器中设置过字符编码后,在servlet里就不要再设置了!如果把编码当成加密的话,加密两次,而只解密一次,那自然是得不到正确答案的。
首先是在web.xml
里加上如下代码,init-param
是在web.xml
里就初始化要使用的编码,当然也可以在代码里直接硬编码咯:
<filter>
<filter-name>CharacterFilter</filter-name>
<filter-class>filter.CharacterFilter</filter-class>
<init-param>
<param-name>character</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
然后是过滤器CharacterFilter
:
package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
/*
* 过滤器,对所有servlet和jsp都生效,用于过滤字符编码
**/
public class CharacterFilter implements Filter{
//保存字符编码的类型,这个被设置在web.xml中
private String character;
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
//强转
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//对post编码进行设置
servletRequest.setCharacterEncoding(character);
//对响应编码(post和get方式的响应是相同的)
response.setContentType("text/html;charset="+ character);
response.setCharacterEncoding(character);
//对get编码进行设置
filterChain.doFilter(new CharacterEncodingForGet(request),response);
}
@Override
public void init(FilterConfig fc) throws ServletException {
character = fc.getInitParameter("character");
}
}
/*
* 对Get方式的请求参数进行编码
* */
class CharacterEncodingForGet extends HttpServletRequestWrapper{
private HttpServletRequest request = null;
public CharacterEncodingForGet(HttpServletRequest request) {
super(request);
this.request = request;
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if(value == null){
return null;
}
String method = request.getMethod();
if("get".equalsIgnoreCase(method)){
try{
value = new String(value.getBytes("ISO8859-1"),request.getCharacterEncoding());
}catch(Exception e){
e.printStackTrace();
}
}
return value;
}
}