美文网首页
统一全站字符编码案例

统一全站字符编码案例

作者: 嗷老板 | 来源:发表于2018-04-02 22:26 被阅读0次

      我们在现实生活中,中文网站的编码都需要进行设置,否则会出现乱码,我们之前已经讲解过解决乱码问题的方法,但是那些方法太麻烦,我们每次创建一个Servlet就需要对其进行设置,所以我们通过设置Filter的方法,对整个网站的编码进行设置。

    第一步:创建注册表单

      我们将注册表单的提交地址使用el表达式进行表示,先使用post请求方式。

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!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>Insert title here</title>
    </head>
    <body>
        <h1>注册页面</h1>
        <hr />
        <form action="${pageContext.request.contextPath}/RegisterServlet " method="post">
        姓名:<input type="text" name="name">
        <br />
        年龄:<input type="text" name="age"/>
        <br />
        <input type="submit" value="注册" />
        </form>
    </body>
    </html>
    

    第二步:编写RegisterSrevlet

      这一步我们需要获取表单提交的数据,并将数据发送到控制台,我们先使用以前的方法处理乱码问题,然后进行测试。

    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 RegisterServlet extends HttpServlet {
        
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //设置响应的编码
            response.setContentType("text/html;charset=UTF-8");
            
            //获取字符输出流对象
            PrintWriter out = response.getWriter();
            
            //设置请求的编码,设置获取表单提交数据的编码
            request.setCharacterEncoding("UTF-8");
            //获取表单提交的数据
            String name = request.getParameter("name");
            String age = request.getParameter("age");
            
            System.out.println(name);
            System.out.println(age);
            
            out.println("注册成功!");
            
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    }
    
    浏览器
    控制台

    第三步:创建EncodingFilter

      上一步中的设置编码的方法复用性太低,所以我们创建一个EncodingFilter,设置web.xml配置文件中的属性,让他拦截所有的请求响应,然后设置请求响应的编码,在doFIlter方法中对参数进行强转并设置编码,最后将RegisterServlet中的编码设置注释掉并进行测试,结果和上面相同。

    import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class EncodingFilter implements Filter {
    
        public EncodingFilter() {
            // TODO Auto-generated constructor stub
        }
    
        public void destroy() {
            // TODO Auto-generated method stub
        }
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse res = (HttpServletResponse) response;
            
            //设置请求的编码
            req.setCharacterEncoding("UTF-8");
            //设置响应的编码
            res.setContentType("text/html;charset=UTF-8");
            
            chain.doFilter(req, res);
        }
    
        public void init(FilterConfig fConfig) throws ServletException {
            // TODO Auto-generated method stub
        }
    
    }
    

    为什么要进行强转
      我们说doFilter方法执行后会把请求和响应对象传给Servlet中的doGet方法执行,doGet方法的参数是HttpServletRequest和HttpServletResponse,同时所以需要强转。
    对配置文件进行设置
      将配置文件中EncodingFilter对应的url-pattern标签的属性修改为“/*”,代表该web项目下的所有页面。

    <filter>
        <display-name>EncodingFilter</display-name>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>com.itheima.filter.EncodingFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
    

    第四步:创建一个增强版的request类

      之前我们的设置是针对post请求方式的表单,但是不适用于请求方式是get的表单,所以我们接下来需要进行设置,使请求方式为get的表单的乱码问题得到解决。
      我们获得请求方式为get的表单数据时,是通过getParameter方法进行获取的,我们可以通过重写getParameter方法对编码进行设置。getParameter方法是HttpServletRequest接口的抽象方法,如果我们直接实现HttpServletRequest接口,需要实现接口中所有的方法,非常麻烦,所以我们可以继承一个实现HttpServletRequest接口的类HttpServletRequestWrapper,然后重写getParameter方法,并修改EncodingFilter中的doFilter方法,最后修改表单的提交方式进行测试。

    import java.io.UnsupportedEncodingException;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    public class MyHttpServletRequest extends HttpServletRequestWrapper{
    
        public MyHttpServletRequest(HttpServletRequest request) {
            super(request);
            // TODO Auto-generated constructor stub
        }
        
        @Override
        public String getParameter(String name){
            //首先获取网页的请求方式
            String method = super.getMethod();
            //如果请求方式是get
            if("GET".equals(method)){
                //获取表单提交的数据
                String value = super.getParameter(name);
                try {
                    return new String(value.getBytes("ISO-8859-1"),"UTF-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            //因为我们在EncodingFilter中已经对post方式进行了设置,这里就不用在进行设置了
            return super.getParameter(name);
        }
    
    }
    

    修改EncodingFilter中的doFilter方法

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest req = new MyHttpServletRequest((HttpServletRequest) request);
            HttpServletResponse res = (HttpServletResponse) response;
            
            //设置请求的编码
            req.setCharacterEncoding("UTF-8");
            //设置响应的编码
            res.setContentType("text/html;charset=UTF-8");
            
            chain.doFilter(req, res);
        }
    

    第五步:使用Filter的初始化参数设置编码

      我们在开发过程中,如果按照上面的步骤设置,需要修改编码的时候,必须修改源码;如果我们把编码信息写入配置文件中,修改编码的时候就可以直接修改配置文件,这样就方便了许多。
    修改配置文件

     <filter>
        <display-name>EncodingFilter</display-name>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>com.itheima.filter.EncodingFilter</filter-class>
        
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
    

    **在EncodingFilter中获取初始化参数并赋值给成员变量,然后重新设置编码

    import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class EncodingFilter implements Filter {
    
        private String encoding;
        public EncodingFilter() {
            // TODO Auto-generated constructor stub
        }
    
        public void destroy() {
            // TODO Auto-generated method stub
        }
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest req = new MyHttpServletRequest((HttpServletRequest) request,enconding);
            HttpServletResponse res = (HttpServletResponse) response;
            
            //设置请求的编码
            req.setCharacterEncoding(encoding);
            //设置响应的编码
            res.setContentType("text/html;charset="+encoding);
            
            chain.doFilter(req, res);
        }
    
        public void init(FilterConfig fConfig) throws ServletException {
            String encoding = fConfig.getInitParameter("encoding");
            this.encoding = encoding;
        }
    
    }
    

    修改自定义类MyHttpServletRequest类中的编码,通过构造方法传递encoding参数

    import java.io.UnsupportedEncodingException;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    public class MyHttpServletRequest extends HttpServletRequestWrapper{
        private String encoding;
        public MyHttpServletRequest(HttpServletRequest request,String encoding) {
            super(request);
            this.encoding = encoding;
        }
        
        @Override
        public String getParameter(String name){
            //首先获取网页的请求方式
            String method = super.getMethod();
            //如果请求方式是get
            if("GET".equals(method)){
                //获取表单提交的数据
                String value = super.getParameter(name);
                try {
                    return new String(value.getBytes("ISO-8859-1"),encoding);
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            //因为我们在EncodingFilter中已经对post方式进行了设置,这里就不用在进行设置了
            return super.getParameter(name);
        }
    
    }
    

    最终结果:

    浏览器
    控制台

    相关文章

      网友评论

          本文标题:统一全站字符编码案例

          本文链接:https://www.haomeiwen.com/subject/pewxhftx.html