问题:
我们经常在servlet中处理网站的请求参数乱码问题,
例如在post请求中,需要我们写request.setCharacterEncoding(“utf-8”);
但是在get请求中,需要分两步来处理:
- 先得到参数,例如:
String username = request.getParameter("username");
- 然后进行重新编码:例如:
username = new String(username.getBytes("ISO-8859-1"),"utf-8");
演示一下乱码
我们新建一个index.jsp,包含有以下简单的代码:
<body>
<a href="<c:url value='AServlet?username=刘伟佳'/>">点击这里</a>
<br />
<form action="<c:url value='/AServlet'/>" method="post">
用户名
<input type="text" name="username" value="刘伟佳">
<input type="submit" value="提交">
</form>
</body>
效果为:
接下来我们新建一个servlet,包含有doget()
方法和dopost()
方法,并且不处理请求编码问题,只处理响应编码问题,回显到我们页面上,我们看一下会出现什么状况。
AServlet:
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
response.getWriter().println(username);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
response.getWriter().println(username);
}
}
我们点击这个超链接,
看到页面是没有问题的,笔者使用的浏览器为Chrome,但是有些浏览器上这里也是会出现乱码的。
我们如果点击下面的表单提交,
我们可以看到是乱码的:
使用过滤器解决!
我们新建一个过滤器,让它过滤所有的资源:
在这个过滤器里面,首先要处理post的请求编码问题,这个比较简单,一句话即可:
// 处理post请求编码问题
request.setCharacterEncoding("utf-8");
而在处理get请求的时候,稍微复杂一点,我们要把request“调包”,我们自己写一个request的装饰类。
request的装饰类:
我们要改写大部分的方法,并且在getParameter方法中处理乱码问题。
/**
* 装饰request
* @author Veeja.Liu
* @emial veejaliu@gmail.com
*
*/
// 使用装饰者模式
public class EncodingRequest implements HttpServletRequest{
private HttpServletRequest request;
public EncodingRequest(HttpServletRequest request){
this.request = request;
}
public Object getAttribute(String arg0) {
// TODO Auto-generated method stub
return request.getAttribute(arg0);
}
......
public String getParameter(String arg0) {
String value = request.getParameter(arg0);
// 处理编码问题
try {
value = new String(value.getBytes("iso-8859-1"),"utf-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return value;
}
......
}
我们在filter中应该使用我们自检创建的类进行“调包”。
最终形成以下处理get请求中的编码问题的代码。
/**
* 处理get请求的编码问题。
*/
/*
* 调包request. 1. 写一个request的装饰类 2. 在放行的时候使用我们自己的request
*/
// 先做一个类型转换
HttpServletRequest req = (HttpServletRequest) request;
EncodingRequest er = new EncodingRequest(req);
chain.doFilter(er, response);
而在上面我们自己写的类中,我们需要一个一个的改写类中的方法,来供我们使用,其实我们已经有了这样的东西,供我们“调包”使用,就是Wrapper类。所以上面的装饰者类,我们可以写为:
/**
* 装饰request
*
* @author Veeja.Liu
* @emial veejaliu@gmail.com
*
*/
// 使用装饰者模式
public class EncodingRequest extends HttpServletRequestWrapper {
private HttpServletRequest req;
public EncodingRequest(HttpServletRequest request) {
super(request);
this.req = request;
}
public String getParameter(String arg0) {
String value = req.getParameter(arg0);
// 处理编码问题
try {
value = new String(value.getBytes("iso-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return value;
}
}
最后我们形成的filter类代码如下:
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 处理post请求编码问题
request.setCharacterEncoding("utf-8");
/**
* 处理get请求的编码问题。 调包request. 1. 写一个request的装饰类 2. 在放行的时候使用我们自己的request
*/
// 先做一个类型转换
HttpServletRequest req = (HttpServletRequest) request;
if (req.getMethod().equals("GET")) {
EncodingRequest er = new EncodingRequest(req);
chain.doFilter(er, response);
} else if (req.getMethod().equals("POST")) {
chain.doFilter(request, response);
}
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
最后我们测试两种请求方式,都没有发现乱码问题了。
当然,例如我这台机器,get方式是没有乱码问题的,这样我们只解决post的乱码问题就可以了。根据自己的机器运行情况做调整即可!
END.