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

统一全站字符编码案例

作者: 嗷老板 | 来源:发表于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);
    }

}

最终结果:

浏览器
控制台

相关文章

  • 统一全站字符编码案例

      我们在现实生活中,中文网站的编码都需要进行设置,否则会出现乱码,我们之前已经讲解过解决乱码问题的方法,但是那些...

  • Filter的两个应用案例(学习笔记)

      下面梳理一下Filter的两个应用案例,同时将之前的知识点串联起来。 案例1:使用Filter实现统一全站编码...

  • imsdk 数据库设计

    字符编码,字符集 后面 字符编码,字符集统一 CHARACTER SET utf8mb4 COLLATE utf...

  • python2,python3的字符编码 和 字符类型

    字符编码 一开始制定字符编码只考虑了英文 ASCII编码表(包含英文、数字和常用字符), 0~127 为了统一,诞...

  • 关于JS中字符串的编码

    字符编码 Unicode 作为字符编码的标准,它用码位(code point)来索引某个字符(全球统一标识符),字...

  • 使用Filter来统一全站编码

    由于请求方式get和post的解决乱码方式是不一样的。 post请求方式的参数是存放在消息体中,可以通过setCh...

  • 【备忘】UNICODE&UTF

    ascii是英语的编码统一了全球字符语言的字符集是unicodeunicode编码方式称为UTF。 将unicod...

  • ucs

    unicode编码方式 统一码(unicode)的编码方式使用的是通用字符集UCS unicode字符的平面映射本...

  • Python中的编码问题

    1. 什么是编码? 编码,准确点讲是字符编码,其实就是文本,数字,符号等各种各样的字符统一用数字来表示。 因为计算...

  • Web 基础21 Filter 入门案例一 ~ 统一全站的编码

      不知道大家发现没有上一小节我其实什么都没有讲,就只是放了自己的代码,没有Filter,每一个Servlet里面...

网友评论

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

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