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

zhanglei 2022年06月20日 560次浏览

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

15.1 回顾 CharacterEncodingFilter

15.1.1 CharacterEncodingFilter 的成员属性

image-20220620094058867

image-20220620094058867

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

15.1.2 CharacterEncodingFilter 的使用情景

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

​ 项目结构:

image-20220620103029706

image-20220620103029706

15.2 在 springboot 中使用

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

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

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

image-20220620095635347

image-20220620095635347

​ 并且把编码设置取消:

image-20220620095938026

image-20220620095938026

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

image-20220620100056203

image-20220620100056203

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

image-20220620100435457

image-20220620100435457

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

15.2.2 用CharacterEncodingFilter 解决中文乱码

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

配置类:(配置 Servlet 和 CharacterEncodingFilter)

  1. package com.zhanglei.config;
  2. import com.zhanglei.web.MyServlet;
  3. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  4. import org.springframework.boot.web.servlet.ServletRegistrationBean;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.web.filter.CharacterEncodingFilter;

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

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

  17. return servlet;
  18. }

  19. //配置 Filter
  20. @Bean
  21. public FilterRegistrationBean getFilter(){
  22. FilterRegistrationBean encodingFilter=
  23. new FilterRegistrationBean();
  24. //使用框架中的过滤器类
  25. CharacterEncodingFilter filter=
  26. new CharacterEncodingFilter();
  27. //指定编码方式
  28. filter.setEncoding("utf-8");
  29. //指定请求端和相应端使用的编码均为 utf-8
  30. filter.setForceRequestEncoding(true);
  31. filter.setForceResponseEncoding(true);
  32. //配置 过滤器
  33. encodingFilter.setFilter(filter);

  34. return encodingFilter;
  35. }
  36. }

创建的Servlet 类:

  1. package com.zhanglei.web;
  2. import javax.servlet.ServletException;
  3. import javax.servlet.http.HttpServlet;
  4. import javax.servlet.http.HttpServletRequest;
  5. import javax.servlet.http.HttpServletResponse;
  6. import java.io.IOException;
  7. import java.io.PrintWriter;

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

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

15.2.3 验证 CharacterEncodingFilter

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

image-20220620103449736

image-20220620103449736

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

image-20220620103810618

image-20220620103810618

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

image-20220620104144273

image-20220620104144273

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

springboot 自动装配了一些属性,比如服务器端口,以及项目上下文(项目名),默认的配置信息存在 包名字以 *-autoconfigure.jar 形式结尾的jar包中,springboot的默认配置文件的名字为:/META-INF/spring-configuration-metadata.json,如下:
image-20220620125152708

image-20220620125152708


打开发现,服务器的默认端口号是8080,如下:
image-20220620125301466

image-20220620125301466


项目名默认为空:
image-20220620125458244

image-20220620125458244


自动配置的字符过滤器默认开启:
image-20220620125621516

image-20220620125621516


…以及其他配置默认信息,并且springboot 将这些都封装成了xxx.properties 类,这个类加上了 @ConfigurationProperty注解,让我们可以通过配置文件来修改默认值! 打开sever.properties 类:
image-20220620130012495

image-20220620130012495


因此我们只需要在 properties文件里面做如下配置:

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

就可以将 项目上下文改成 /zhanglei ,以及设置 encoding 的三个属性,使得请求端和响应端都使用 utf-8 的编码方式。
打开浏览器,输入:localhost:8080/zhanglei/myservlet
image-20220620130927259

image-20220620130927259


这样就不要手动定义 filter 了,直接用 springboot 自动配置的,我们要做的就是通过 properties 或者 yaml 文件修改 属性的默认值!