你的位置:首页 > Java教程

[Java教程]解决全站字符乱码(POST和GET中文编码问题)


其实全站乱码问题的难点就是处理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);  }