JavaWeb——Get、Post请求中文乱码问题

  最近在重温JavaWeb基础内容,碰到了之前也时常遇到的中文乱码问题,想着反正是经常要处理的,不如当即就把它整理出来放在博客里,省得遇到时再去到处搜。

  1. Post请求乱码的解决方案:

   手工创建一个过滤器实现javax.servlet.Filter接口:

public class CharacterEncodingFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        //解决以Post方式提交的中文乱码问题
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }

}

  在web.xml中配置该过滤器:

  <filter>
     <filter-name>CharacterEncodingFilter</filter-name>
     <filter-class>cn.lby.filter.CharacterEncodingFilter</filter-class>
  </filter>
  <filter-mapping>
     <filter-name>CharacterEncodingFilter</filter-name>
     <url-pattern>/*</url-pattern>
  </filter-mapping>

  当然,实际开发中一般不会去自己做这个Filter,都是利用框架里封装好的,传参也能通过配置来完成,十分方便,比如spring通常我们会在web.xml中写入下面的代码:

    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

 2. Get请求乱码的解决方案:

  在字符过滤器中使用动态代理解决中文乱码:

public class CharacterEncodingFilter implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
        //解决以Post方式提交的中文乱码问题
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        
        ServletRequest requestProxy = getHttpServletRequestProxy((HttpServletRequest)request);
        chain.doFilter(requestProxy, response);
	}

	@Override
	public void destroy() {

	}

    /**
    * @Method: getHttpServletRequestProxy
    * @Description: 获取HttpServletRequest对象的代理对象
    * @param request
    * @return HttpServletRequest对象的代理对象
    */ 
    private ServletRequest getHttpServletRequestProxy(final HttpServletRequest request){
        ServletRequest proxy  = (ServletRequest) Proxy.newProxyInstance(
                CharacterEncodingFilter.class.getClassLoader(),
                request.getClass().getInterfaces(),
                new InvocationHandler(){
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {
                        //如果请求方式是get并且调用的是getParameter方法
                        if (request.getMethod().equalsIgnoreCase("get") && method.getName().equals("getParameter")) {
                            //调用getParameter方法获取参数的值
                            String value = (String) method.invoke(request, args);
                            if(value==null){
                                return null;
                            }
                            //解决以get方式提交的中文乱码问题
                            return new String(value.getBytes("iso8859-1"),"UTF-8");
                        }else {
                            //直接调用相应的方法进行处理
                            return method.invoke(request, args);
                        }
                    }
                });
        //返回HttpServletRequest对象的代理对象
        return proxy;
    }
    

}

  如果觉得上面的方式太繁琐,也可以通过修改 tomcat 的 server.xml 配置文件:

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

  改成:

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>

  注: 如果是ajax发起的get请求中文依然会乱码,这时候需要把 useBodyEncodingForURI="true" 改为 URIEncoding="UTF-8" 。

  下面是测试两种乱码问题解决方案的 demo ,如果懒得写可以参考一下:

  首先是jsp页面:

<!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、post请求方式下的中文乱码问题</title>
  body {
    text-align: center;
      padding: 60px 150px;
      margin-right: 150px;
      line-height: 2.0em;
    }
</head>

<body>
       
      <%--使用get的方式访问 --%>
       <a onclick="myClick()" href="javascript:void(0)">超链接(get方式请求)</a>

       <hr/>

       <form action="EncodingServlet" method="post">
               用户名:<input type="text" name="username" value="彬爷" />
           <input type="submit" value="post方式提交">
       </form>
       
       
       <script type="text/javascript">
              function myClick() {
          window.location.href = "EncodingServlet?username=彬爷";    
            }
       </script>
       
</body>

</html>

  后台服务:

public class EncodingServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public EncodingServlet() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String method = request.getMethod();
        PrintWriter out = response.getWriter();
        System.out.println("请求方式为:" + method);
        out.write("请求方式为:" + method);
        out.write("<br/>");
        System.out.println("请求参数为:" + username);
        out.write("请求参数为:" + username);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

  web.xml 中的 Servlet 配置我这里就不发了。

原文地址:https://www.cnblogs.com/binye-typing/p/6281627.html