其实全站乱码问题的难点就是处理GET请求参数的问题。
如果只是处理POST请求的编码问题,以及响应编码问题,这个就很好解决了response.setContentType("text/html;charset=utf-8");和request.setCharacterEncoding("utf-8");就可以解决的
好了,这里主要的就是解决GET请求参数的问题,我使用的方式是用过滤器(拦截器)Filter来解决,
我的思路是:
首先定义一过滤器allDecodingFilter的过滤器,这个过滤器是过滤全站的所有文件(<url-pattern>/*</url-pattern>),
1.要解决GET请求参数的问题,我们首先定义一个装饰类(这里涉及到了装饰者模式),装饰类通俗一点的说法就是把原有的类的方法或属性进行再改造。我就定义一个名为DecodingRequest的装饰类,这个类必须继承HttpServletRequestWrapper类,因为这个类继承了HttpServletRequest接口,并实现HttpServletRequest接口的所有方法,那么只要我继承了HttpServletRequestWrapper类就可以对该类里面的方法再重写了(有兴趣的话可以去看看j2ee源码)。这里主要就是重写getParameter(String name)方法。
2.回到过滤器中,我就可以把我自己定义的DecodingRequest类传递给Servlet的doget()和dopost()方法,那么当需要获取参数调用getParameter(String name)时,其实就是调用自己定义的getParameter(String name)方法,那么就不会出现乱码了。口述的可能不好,我还是通过代码来说话吧
过滤器allDecodingFilter:
public class allDecodingFilter implements Filter { public void destroy() { } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; //处理响应编码 HttpServletResponse reps = (HttpServletResponse) response; response.setContentType("text/html;charset=utf-8"); // 处理post请求参数的乱码 request.setCharacterEncoding("utf-8"); // 若是Get请求方式就使用装饰类的获取的参数的方法 if (req.getMethod().equals("GET")) { HttpServletRequest newReq = new DecodingRequest(req);//这个类下一步会陈述 /* * 调包request 1. 自己定义的request的装饰类 2. 在拦截通过时,使用我们自己定义request 3. * 在Servlet中 * ,只有你调用request.getParameter(name)方法本质就是执行自己定义的request.getParameter * (name)方法 */ chain.doFilter(newReq, response); } else { // 若是post方式就不使用装饰类 chain.doFilter(request, response); } } public void init(FilterConfig fConfig) throws ServletException { } }
装饰类DecodingRequest
/** *装饰类(这是装饰者模式) *HttpServletRequestWrapper:这个类帮我们实现了HttpServletRequest接口所有的方法, *那么我们就可以根据自己的需求对其里面的方法再进行实现 */ public class DecodingRequest extends HttpServletRequestWrapper { private HttpServletRequest req; public DecodingRequest(HttpServletRequest request) { super(request); this.req=request; } /** * 获取到参数进而修改编码方式,当用户获取参数的时候就是执行了这个方法了 */ @Override public String getParameter(String name) { try { //修改字符编码方式 name=new String(req.getParameter(name).getBytes("iso-8859-1"),"utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return name; } }
Servlet测试类
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //这里实质调用的是DecodingRequest类中的request.getParameter("uname");方法 String name = request.getParameter("uname"); System.out.println(name); response.getWriter().print(name); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("uname"); System.out.println(name); response.getWriter().print(name); }