javaWeb----Filter-------全栈编码问题

解决全站字符乱码(POST和GET中文编码问题)
1 说明
乱码问题:
 获取请求参数中的乱码问题;
 POST请求:request.setCharacterEncoding(“utf-8”);
 GET请求:new String(request.getParameter(“xxx”).getBytes(“iso-8859-1”), “utf-8”);
 响应的乱码问题:response.setContextType(“text/html;charset=utf-8”)。

  基本上在每个Servlet中都要处理乱码问题,所以应该把这个工作放到过滤器中来完成。
如果是POST请求,当执行目标Servlet时,Servlet中调用request.getParameter()方法时,就会根据request.setCharacterEncoding()设置的编码来转码!这说明在过滤器中调用request.setCharacterEncoding()方法会影响在目标Servlet中的request.getParameter()方法的行为!
但是如果是GET请求,我们又如何能影响request.getParameter()方法的行为呢?这是不好做到的!我们不可能先调用request.getParameter()方法获取参数,然后手动转码后,再施加在到request中!因为request只有getParameter(),而没有setParameter()方法。

处理GET请求参数编码问题,需要在Filter中放行时,把request对象给“调包”了,也就是让目标Servlet使用我们“调包”之后的request对象。这说明我们需要保证“调包”之后的request对象中所有方法都要与“调包”之前一样可以使用,并且getParameter()方法还要有能力返回转码之后的参数。

这可能让你想起了“继承”,但是这里不能用继承,而是“装饰者模式(Decorator Pattern)”!
下面是三种对a对象进行增强的手段:
 继承:AA类继承a对象的类型:A类,然后重写fun1()方法,其中重写的fun1()方法就是被增强的方法。但是,继承必须要知道a对象的真实类型,然后才能去继承。如果我们不知道a对象的确切类型,而只知道a对象是IA接口的实现类对象,那么就无法使用继承来增强a对象了;
 装饰者模式:AA类去实现a对象相同的接口:IA接口,还需要给AA类传递a对象,然后在AA类中所有的方法实现都是通过代理a对象的相同方法完成的,只有fun1()方法在代理a对象相同方法的前后添加了一些内容,这就是对fun1()方法进行了增强;
 动态代理:动态代理与装饰者模式比较相似,而且是通过反射来完成的。动态代理会在最后一天的基础加强中讲解,这里就不再废话了。

对request对象进行增强的条件,刚好符合装饰者模式的特点!因为我们不知道request对象的具体类型,但我们知道request是HttpServletRequest接口的实现类。这说明我们写一个类EncodingRequest,去实现HttpServletRequest接口,然后再把原来的request传递给EncodingRequest类!在EncodingRequest中对HttpServletRequest接口中的所有方法的实现都是通过代理原来的request对象来完成的,只有对getParameter()方法添加了增强代码!
JavaEE已经给我们提供了一个HttpServletRequestWrapper类,它就是HttpServletRequest的包装类,但它做任何的增强!你可能会说,写一个装饰类,但不做增强,其目的是什么呢?使用这个装饰类的对象,和使用原有的request有什么分别呢?
HttpServletRequestWrapper类虽然是HttpServletRequest的装饰类,但它不是用来直接使用的,而是用来让我们去继承的!当我们想写一个装饰类时,还要对所有不需要增强的方法做一次实现是很心烦的事情,但如果你去继承HttpServletRequestWrapper类,那么就只需要重写需要增强的方法即可了。

index.jsp

<body>
    <a href="<c:url value='LoginServlet?username=李四'/>">点击这里</a>
    <form action="<c:url value='LoginServlet'/>" method="post">
    <input type="text" name="username" value="张三">
    <input type="submit" value="提交"> 
    </form>
  </body>

EncondingFilter

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //处理post请求
        request.setCharacterEncoding("utf-8");
        HttpServletRequest req = (HttpServletRequest) request;

        if(req.getMethod().equals("GET")){
            EncondingRequest er = new EncondingRequest(req);
            chain.doFilter(er, response);
        }else if(req.getMethod().equals("POST")){
            chain.doFilter(request, response);
        }


    }

EncondingRequest

package cn.lq.filter;

import java.io.UnsupportedEncodingException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class EncondingRequest extends HttpServletRequestWrapper{
    /**
     * 这里是使用装饰类来进行的
     */
    //最好存一个底层对象
    private HttpServletRequest req;
    public EncondingRequest(HttpServletRequest request) {
        super(request);
        this.req = request;
    }
    //重写方法
    public String getParameter(String name){
        String value = req.getParameter(name);
        //处理编码问题
        try {
            value = new String(value.getBytes("iso-8859-1"),"utf-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        return value;
    }

}

LoginServlet

package cn.lq.servlet;

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 LoginServlet extends HttpServlet {


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        System.out.println(request.getParameter("username"));
    }
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        System.out.println(request.getParameter("username"));
    }

}

猜你喜欢

转载自blog.csdn.net/ilikejj0/article/details/80306200