1、首先看一个装饰模式解决字符集编码问题
我们使用装饰者对request进行增强,从而使得get和post使用request.getParameter()获得的数据没有乱码:
首先来一个Servlet,用于处理客户端请求:
package 装饰者模式解决乱码; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DataServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DataServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获得数据 String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("前:" +username+"@"+password); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获得数据 String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println("前:" +username+"@"+password); } }
创建HttpServletRequest的增强类,借助HttpServletRequestWrapper:
package 装饰者模式解决乱码; import java.io.UnsupportedEncodingException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; /** * * sun 提供 HttpServletRequest 接口使用装饰者编写默认类,及所有的方法都没有增强的。 * * 之后我们只需要继承即可 * * 增强response对象,提供使用装饰者设计模式编写默认类:HttpServletResponseWrapper */ public class MyRequest extends HttpServletRequestWrapper { //保持对接口的引用 private HttpServletRequest request; //构造方法 public MyRequest(HttpServletRequest request) { super(request); //赋值 this.request = request; } //重写某个方法 @Override public String getParameter(String name) { //首先获得参数,这是没有改变编码的值 String value = request.getParameter(name); //首先判断请求方式 String method = request.getMethod(); if ("GET".equals(method)) { try { value = new String(value.getBytes("ISO-8859-1"), "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } }else { try { request.setCharacterEncoding("utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return value; } }
在客户端向服务器发送请求时,我们需要对其进行拦截:
package 装饰者模式解决乱码; 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() { } public void destroy() { } public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { //强转 HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; //post编码 response.setCharacterEncoding("UTF-8"); //使用装饰者模式增强 MyRequest myRequest = new MyRequest(request); //放行 chain.doFilter(myRequest, response); System.out.println("我是中国人!"); /*//0 强转 HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; //1 post乱码 request.setCharacterEncoding("UTF-8"); //2 使用装饰者增强request MyRequest myRequest = new MyRequest(request); chain.doFilter(myRequest, response);*/ } public void init(FilterConfig fConfig) throws ServletException { } }
2、动态代理解决
客户端页面:
<%@ 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>动态代理解决get方式乱码问题</title> </head> <body> <form action="/proxy/DataServlet" method="get"> 用户名:<input type="text" name="username" value="胡根得" /><br/> 密码:<input type="password" name=password value="就不告诉你"><br/> <input type="submit" value="提交get请求"> </form> </body> </html>
写一个Servlet:
package solveresponseencoding; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/DataServlet") public class DataServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DataServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获得请求参数 String username = request.getParameter("username"); String password = request.getParameter("password"); //打印值 System.out.println(request.getMethod() + " : " + username + " @ " + password); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
<span style="font-size:18px;">package solveresponseencoding; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; 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.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebFilter("/*") public class EncodingFilter implements Filter { public EncodingFilter() { } public void destroy() { } /* * 本方法会拦截所有请求,在本方法中对request进行增强 */ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { //强转 final HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; //解决post乱码 request.setCharacterEncoding("utf-8"); //创建动态代理对象 HttpServletRequest myRequest = (HttpServletRequest) Proxy.newProxyInstance( EncodingFilter.class.getClassLoader(), new Class[]{HttpServletRequest.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //如果是getParameter方法,获取参数 if ("getParameter".equals(method.getName())) { String value = request.getParameter((String)args[0]); //System.out.println("value值为:"+value); //如果是get请求,就增强 if ("GET".equalsIgnoreCase(request.getMethod())) { value = new String(value.getBytes("ISO-8859-1"), "utf-8"); System.out.println("我是get方法:"); } return value; } return method.invoke(request, args); } }); chain.doFilter(myRequest, response); } public void init(FilterConfig fConfig) throws ServletException { } } </span>