我们在现实生活中,中文网站的编码都需要进行设置,否则会出现乱码,我们之前已经讲解过解决乱码问题的方法,但是那些方法太麻烦,我们每次创建一个Servlet就需要对其进行设置,所以我们通过设置Filter的方法,对整个网站的编码进行设置。
第一步:创建注册表单
我们将注册表单的提交地址使用el表达式进行表示,先使用post请求方式。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>注册页面</h1>
<hr />
<form action="${pageContext.request.contextPath}/RegisterServlet " method="post">
姓名:<input type="text" name="name">
<br />
年龄:<input type="text" name="age"/>
<br />
<input type="submit" value="注册" />
</form>
</body>
</html>
第二步:编写RegisterSrevlet
这一步我们需要获取表单提交的数据,并将数据发送到控制台,我们先使用以前的方法处理乱码问题,然后进行测试。
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RegisterServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应的编码
response.setContentType("text/html;charset=UTF-8");
//获取字符输出流对象
PrintWriter out = response.getWriter();
//设置请求的编码,设置获取表单提交数据的编码
request.setCharacterEncoding("UTF-8");
//获取表单提交的数据
String name = request.getParameter("name");
String age = request.getParameter("age");
System.out.println(name);
System.out.println(age);
out.println("注册成功!");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
浏览器
控制台
第三步:创建EncodingFilter
上一步中的设置编码的方法复用性太低,所以我们创建一个EncodingFilter,设置web.xml配置文件中的属性,让他拦截所有的请求响应,然后设置请求响应的编码,在doFIlter方法中对参数进行强转并设置编码,最后将RegisterServlet中的编码设置注释掉并进行测试,结果和上面相同。
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.HttpServletResponse;
public class EncodingFilter implements Filter {
public EncodingFilter() {
// TODO Auto-generated constructor stub
}
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
//设置请求的编码
req.setCharacterEncoding("UTF-8");
//设置响应的编码
res.setContentType("text/html;charset=UTF-8");
chain.doFilter(req, res);
}
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
为什么要进行强转
我们说doFilter方法执行后会把请求和响应对象传给Servlet中的doGet方法执行,doGet方法的参数是HttpServletRequest和HttpServletResponse,同时所以需要强转。
对配置文件进行设置
将配置文件中EncodingFilter对应的url-pattern标签的属性修改为“/*”,代表该web项目下的所有页面。
<filter>
<display-name>EncodingFilter</display-name>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.itheima.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
第四步:创建一个增强版的request类
之前我们的设置是针对post请求方式的表单,但是不适用于请求方式是get的表单,所以我们接下来需要进行设置,使请求方式为get的表单的乱码问题得到解决。
我们获得请求方式为get的表单数据时,是通过getParameter方法进行获取的,我们可以通过重写getParameter方法对编码进行设置。getParameter方法是HttpServletRequest接口的抽象方法,如果我们直接实现HttpServletRequest接口,需要实现接口中所有的方法,非常麻烦,所以我们可以继承一个实现HttpServletRequest接口的类HttpServletRequestWrapper,然后重写getParameter方法,并修改EncodingFilter中的doFilter方法,最后修改表单的提交方式进行测试。
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class MyHttpServletRequest extends HttpServletRequestWrapper{
public MyHttpServletRequest(HttpServletRequest request) {
super(request);
// TODO Auto-generated constructor stub
}
@Override
public String getParameter(String name){
//首先获取网页的请求方式
String method = super.getMethod();
//如果请求方式是get
if("GET".equals(method)){
//获取表单提交的数据
String value = super.getParameter(name);
try {
return new String(value.getBytes("ISO-8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//因为我们在EncodingFilter中已经对post方式进行了设置,这里就不用在进行设置了
return super.getParameter(name);
}
}
修改EncodingFilter中的doFilter方法
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = new MyHttpServletRequest((HttpServletRequest) request);
HttpServletResponse res = (HttpServletResponse) response;
//设置请求的编码
req.setCharacterEncoding("UTF-8");
//设置响应的编码
res.setContentType("text/html;charset=UTF-8");
chain.doFilter(req, res);
}
第五步:使用Filter的初始化参数设置编码
我们在开发过程中,如果按照上面的步骤设置,需要修改编码的时候,必须修改源码;如果我们把编码信息写入配置文件中,修改编码的时候就可以直接修改配置文件,这样就方便了许多。
修改配置文件
<filter>
<display-name>EncodingFilter</display-name>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.itheima.filter.EncodingFilter</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>
**在EncodingFilter中获取初始化参数并赋值给成员变量,然后重新设置编码
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.HttpServletResponse;
public class EncodingFilter implements Filter {
private String encoding;
public EncodingFilter() {
// TODO Auto-generated constructor stub
}
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = new MyHttpServletRequest((HttpServletRequest) request,enconding);
HttpServletResponse res = (HttpServletResponse) response;
//设置请求的编码
req.setCharacterEncoding(encoding);
//设置响应的编码
res.setContentType("text/html;charset="+encoding);
chain.doFilter(req, res);
}
public void init(FilterConfig fConfig) throws ServletException {
String encoding = fConfig.getInitParameter("encoding");
this.encoding = encoding;
}
}
修改自定义类MyHttpServletRequest类中的编码,通过构造方法传递encoding参数
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class MyHttpServletRequest extends HttpServletRequestWrapper{
private String encoding;
public MyHttpServletRequest(HttpServletRequest request,String encoding) {
super(request);
this.encoding = encoding;
}
@Override
public String getParameter(String name){
//首先获取网页的请求方式
String method = super.getMethod();
//如果请求方式是get
if("GET".equals(method)){
//获取表单提交的数据
String value = super.getParameter(name);
try {
return new String(value.getBytes("ISO-8859-1"),encoding);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//因为我们在EncodingFilter中已经对post方式进行了设置,这里就不用在进行设置了
return super.getParameter(name);
}
}
最终结果:
控制台
网友评论