15. 在 springboot 里用字符编码过滤器

zhanglei 2022年06月20日 359次浏览

15. 在 springboot 里用字符编码过滤器

15.1 回顾 CharacterEncodingFilter

15.1.1 CharacterEncodingFilter 的成员属性

image-20220620094058867

​ CharacterEncodingFilter 类中有三个成员属性,encoding(String类型),forceRequestEncoding,forceResponseEncoding (boolean 类型),我们在设置编码的时候只需要将 encoding=“utf-8”,另外两个属性值设为 true 即可。

15.1.2 CharacterEncodingFilter 的使用情景

主要用作浏览器端输出中文乱码问题。

​ 项目结构:

image-20220620103029706

15.2 在 springboot 中使用

使用 servlet + CharacterEncodingFilter 解决中文乱码问题

15.2.1 服务器响应给浏览器端的默认编码

​ 回到之前在springboot 里使用 Servlet 的那篇文章,把Servlet 中的响应给浏览器端的数据改成中文的,如下:

image-20220620095635347

​ 并且把编码设置取消:

image-20220620095938026

​ 启动应用之后,在浏览器端输入:localhost:8080/myservlet 发现:

image-20220620100056203

​ 我在浏览器界面打开检查:

image-20220620100435457

​ 发现响应的默认编码是 iso-8859-1,而中文对应的编码是 utf-8,响应时会出现乱码。

15.2.2 用CharacterEncodingFilter 解决中文乱码

​ 在 springmvc 框架中,要在 web.xml 中配置 CharacterEncodingFilter,在 springboot 中要在配置类中配置,之前在关于 springboot 中使用过滤器一文中说过 如何配置自定义过滤器。这边虽然是配置框架自带的过滤器,但配置方式完全一样:

配置类:(配置 Servlet 和 CharacterEncodingFilter)

package com.zhanglei.config;
import com.zhanglei.web.MyServlet;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;

//声明这是一个配置类,等效于xml文件
@Configuration
public class MyConfig {
    //定义一个方法getServlet,返回为 ServletRegistrationBean 类型
    //@Bean 注解是将返回的 bean对象放容器中,让框架能识别,相当于 spring 中的xml
    @Bean
    public ServletRegistrationBean getServlet(){

        ServletRegistrationBean servlet=
                new ServletRegistrationBean<>(new MyServlet(),"/myservlet");

        return servlet;
    }

    //配置 Filter
    @Bean
    public FilterRegistrationBean getFilter(){
        FilterRegistrationBean encodingFilter=
                new FilterRegistrationBean();
    //使用框架中的过滤器类
        CharacterEncodingFilter filter=
                new CharacterEncodingFilter();
    //指定编码方式
        filter.setEncoding("utf-8");
    //指定请求端和相应端使用的编码均为 utf-8
        filter.setForceRequestEncoding(true);
        filter.setForceResponseEncoding(true);
       //配置 过滤器
        encodingFilter.setFilter(filter);

        return encodingFilter;
    }
}

创建的Servlet 类:

package com.zhanglei.web;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //运用 HttpServletResponse,不设置服务器端的编码
        resp.setContentType("text/html");
        PrintWriter pw= resp.getWriter();
        pw.println("欢迎使用 Servlet");
        pw.flush();
        pw.close();
    }
}

15.2.3 验证 CharacterEncodingFilter

​ 启动应用,在浏览器端输入:localhost:8080/myservlet

image-20220620103449736

​ 这就奇怪了,为什么我设置了请求端和响应端的字符编码为 utf-8,为什么在浏览器显示的还是乱码呢?原因是,在 spriongboot 中,有默认的编码集,如果开启,我们自定义的就会失效,因此要将它关闭,可以在 .properties文件中配置:

image-20220620103810618

​ 这个时候应该可以了,重启应用,在浏览器输入:localhost:8080/myservlet

image-20220620104144273

15.3 探究 springboot 自动配置的过滤器源码

springboot 自动装配了一些属性,比如服务器端口,以及项目上下文(项目名),默认的配置信息存在 包名字以 *-autoconfigure.jar 形式结尾的jar包中,springboot的默认配置文件的名字为:/META-INF/spring-configuration-metadata.json,如下:
image-20220620125152708
打开发现,服务器的默认端口号是8080,如下:
image-20220620125301466
项目名默认为空:
image-20220620125458244
自动配置的字符过滤器默认开启:
image-20220620125621516
…以及其他配置默认信息,并且springboot 将这些都封装成了xxx.properties 类,这个类加上了 @ConfigurationProperty注解,让我们可以通过配置文件来修改默认值! 打开sever.properties 类:
image-20220620130012495
因此我们只需要在 properties文件里面做如下配置:

server.servlet.context-path=/zhanglei
server.servlet.encoding.charset=utf-8
server.servlet.encoding.force-request=true
server.servlet.encoding.force-response=true

就可以将 项目上下文改成 /zhanglei ,以及设置 encoding 的三个属性,使得请求端和响应端都使用 utf-8 的编码方式。
打开浏览器,输入:localhost:8080/zhanglei/myservlet
image-20220620130927259
这样就不要手动定义 filter 了,直接用 springboot 自动配置的,我们要做的就是通过 properties 或者 yaml 文件修改 属性的默认值!