zoukankan      html  css  js  c++  java
  • 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 配置我这里就不发了。

  • 相关阅读:
    Java中Class.forName()用法和newInstance()方法详解
    开发和学习中好用的工具
    ubuntu修改默认的apt源
    区块链共识算法总结(PBFT,Raft,PoW,PoS,DPoS,Ripple)
    比特币白皮书:一个点对点的电子现金系统(百度网盘)
    session和cookie的区别
    HTTP中GET,POST和PUT的区别
    三小时快速入门Python终结篇--其他模块导入
    C/C++ 多继承{虚基类,虚继承,构造顺序,析构顺序}
    C++ 实现vector<std:string> 版本
  • 原文地址:https://www.cnblogs.com/binye-typing/p/6281627.html
Copyright © 2011-2022 走看看