【任务案例】使用Filter实现全站统一编码
任务案例
使用Filter实现全站统一编码
任务目标
在Web开发中,经常会遇到中文乱码问题,按照前面所学知识,解决乱码的通常做法都是在Servlet程序中设置编码方式,但是,如果多个Servlet程序都需要设置编码方式,势必会书写大量重复的代码。为了解决上面的问题,可以在Filter中对获取到的请求和响应消息进行编码,从而统一全站的编码方式。
实现步骤
编写form.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body style="text-align: center;">
<center>
<h3>用户登录</h3>
</center>
<a href="<%=request.getContextPath()%>/CharacterServlet?name=聊城职业技术学院&password=123456">单击超链接登录</a>
<form action="<%=request.getContextPath()%>/CharacterServlet" method="post">
<table border="1" width="600px" cellpadding="0" cellspacing="0" align="center">
<tr>
<td height="30">用户名:</td>
<td> <input type="text" name="name" />
</td>
</tr>
<tr>
<td height="30">密 码:</td>
<td> <input type="password" name="password" />
</td>
</tr>
<tr>
<td height="30" colspan="2">
<input type="submit" value="登录" />
<input type="reset" value="重置" />
</td>
</tr>
</table>
</form>
</body>
</html>
创建CharacterServlet
创建CharacterServlet,该类用于获取用户输入的请求参数,并将参数输出到控制台
CharacterServlet.java
@WebServlet("/CharacterServlet")
public class CharacterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
out.println(request.getParameter("name"));
out.println(request.getParameter("password"));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out=response.getWriter();
String name=request.getParameter("name");
name=new String(name.getBytes("iso8859-1"),"utf-8");
out.println(name);
out.println(request.getParameter("password"));
}
}
Post请求可以通过
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
来解决。
Get请求通过:
String name=request.getParameter("name");
name=new String(name.getBytes("iso8859-1"),"utf-8");
来解决。
但是如果每次都写这样的代码有点重复,我们可以对所有的请求进行过滤。
创建过滤器CharacterFilter
编写一个CharacterFilter类,该类用于拦截用户的请求访问,实现统一全站编码的功能。只是针对请求的方式不同,解决乱码的方式也不同。其中,POST方式的请求参数存放在消息体中,可以通过setCharacterEncoding()方法进行设置;而Get方式的请求参数存放在消息头中,必须通过获取URI参数才能进行设置。如果每次单独对GET请求方式进行处理,势必会很麻烦。为此,可以通过HttpServletRequestWrapper类对HttpServletRequest类进行包装,通过重写getParameter()的方式来设置GET方式提交参数的编码。(HttpServletRequestWrapper类是HttpServletRequest的实现类,我们平时定义的HttpServletRequest request的实现类是HttpServletRequestWrapper,在这里我们定义一个类CharacterRequest继承HttpServletRequestWrapper这个实现类,在这个类中重写getParameter方法,然后用CharacterRequest这个类来创建request对象)
CharacterFilter.java
@WebFilter("/*")
public class CharacterFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//拦截所有的请求 解决全站中文乱码
//指定 request 和 response 的编码
request.setCharacterEncoding("utf-8");// 只对消息体有效
response.setContentType("text/html;charset=utf-8");
//对request进行包装
CharacterRequest characterRequest = new CharacterRequest(request);
chain.doFilter(characterRequest,response);
}
public void init(FilterConfig config) throws ServletException {
}
// 继承 默认包装类HttpServletRequestWrapper
class CharacterRequest extends HttpServletRequestWrapper {
private HttpServletRequest request;
public CharacterRequest(HttpServletRequest request) {
super(request);
this.request = request;
}
//子类继承父类一定会覆写一些方法,此处用于重写getParamter()方法
public String getParameter(String name) {
//调用被包装对象的getParameter()方法,获得请求参数
String value = super.getParameter(name);
//调用父类的getParameter方法,得到value值。这里必须调用父类的getParameter,因为本类要重写父类的方法,本类的这个方法还没有父类的那个功能。
if (value == null)
return null;
//判断请求方式
String method = super.getMethod();
if ("get".equalsIgnoreCase(method)) {
try {
value = new String(value.getBytes("iso-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
} //解决乱码后返回结果
return value;
}
}
}
在测试前把 CharacterServlet.java doGet方法中 name=new String(name.getBytes(“iso8859-1”),“utf-8”); 这行代码去掉。运行
http://localhost:8080/form.jsp 单击“单击超链接登录”后,发现也能正常显示中文。