15. 在 springboot 里用字符编码过滤器
15.1 回顾 CharacterEncodingFilter
15.1.1 CharacterEncodingFilter 的成员属性
CharacterEncodingFilter 类中有三个成员属性,encoding(String类型),forceRequestEncoding,forceResponseEncoding (boolean 类型),我们在设置编码的时候只需要将 encoding=“utf-8”,另外两个属性值设为 true 即可。
15.1.2 CharacterEncodingFilter 的使用情景
主要用作浏览器端输出中文乱码问题。
项目结构:
15.2 在 springboot 中使用
使用 servlet + CharacterEncodingFilter 解决中文乱码问题
15.2.1 服务器响应给浏览器端的默认编码
回到之前在springboot 里使用 Servlet 的那篇文章,把Servlet 中的响应给浏览器端的数据改成中文的,如下:
并且把编码设置取消:
启动应用之后,在浏览器端输入:localhost:8080/myservlet 发现:
我在浏览器界面打开检查:
发现响应的默认编码是 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
这就奇怪了,为什么我设置了请求端和响应端的字符编码为 utf-8,为什么在浏览器显示的还是乱码呢?原因是,在 spriongboot 中,有默认的编码集,如果开启,我们自定义的就会失效,因此要将它关闭,可以在 .properties文件中配置:
这个时候应该可以了,重启应用,在浏览器输入:localhost:8080/myservlet
15.3 探究 springboot 自动配置的过滤器源码
springboot 自动装配了一些属性,比如服务器端口,以及项目上下文(项目名),默认的配置信息存在 包名字以 *-autoconfigure.jar 形式结尾的jar包中,springboot的默认配置文件的名字为:/META-INF/spring-configuration-metadata.json,如下:
打开发现,服务器的默认端口号是8080,如下:
项目名默认为空:
、
自动配置的字符过滤器默认开启:
…以及其他配置默认信息,并且springboot 将这些都封装成了xxx.properties 类,这个类加上了 @ConfigurationProperty注解,让我们可以通过配置文件来修改默认值! 打开sever.properties 类:
因此我们只需要在 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
这样就不要手动定义 filter 了,直接用 springboot 自动配置的,我们要做的就是通过 properties 或者 yaml 文件修改 属性的默认值!