概述
该过滤器允许指定字符集处理用户请求或者响应。在浏览器没有对请求指定字符集的情况下,我们可以使用该方案指定使用那种字符集处理请求。
该过滤器应用在请求缺少字符集信息时会应用指定的字符集,但也可以通过设置过滤器属性forceRequestEncoding
为true
强制使用制定给过滤器的字符集。实际上,也可以通过设置过滤器属性forceResponseEncoding
为true
强制响应使用指定给过滤器的字符集。
该过滤器继承自OncePerRequestFilter
,也就是说,它在整个请求处理过程中最多只会被应用一次。
Springboot
提供了一个OrderedCharacterEncodingFilter
继承自CharacterEncodingFilter
应用在基于Springboot
的Web
应用中。OrderedCharacterEncodingFilter
在CharacterEncodingFilter
的功能上增加了接口OrderedFilter
定义的过滤器顺序,并且缺省使用最高优先级。换句话讲,它会是整个过滤器链中第一个被调用的过滤器。
Springboot
缺省会根据配置属性spring.http.encoding
设置OrderedCharacterEncodingFilter
的字符集和forceRequestEncoding
/forceResponseEncoding
。缺省情况下,它们的分别使用:UTF-8
,false
,false
。参考自动配置HttpEncodingAutoConfiguration
。
源代码解析
源代码版本 :
Spring Web 5.1.3
package org.springframework.web.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
public class CharacterEncodingFilter extends OncePerRequestFilter {
// 制定给该过滤器的字符集(也可以理解为编码方式)
@Nullable
private String encoding;
// 是否强制请求使用指定的字符集
private boolean forceRequestEncoding = false;
// 是否强制响应使用指定的字符集
private boolean forceResponseEncoding = false;
// 构造函数 ,执行之后 :
// encoding : null
// forceRequestEncoding : false
// forceResponseEncoding : false
public CharacterEncodingFilter() {
}
// 构造函数 ,执行之后 :
// encoding : 同参数encoding
// forceRequestEncoding : false
// forceResponseEncoding : false
public CharacterEncodingFilter(String encoding) {
this(encoding, false);
}
// 构造函数 ,执行之后 :
// encoding : 同参数encoding
// forceRequestEncoding : 同参数forceEncoding
// forceResponseEncoding : 同参数forceEncoding
public CharacterEncodingFilter(String encoding, boolean forceEncoding) {
this(encoding, forceEncoding, forceEncoding);
}
// 构造函数 ,执行之后 :
// encoding : 同参数encoding
// forceRequestEncoding : 同参数 forceRequestEncoding
// forceResponseEncoding : 同参数 forceResponseEncoding
public CharacterEncodingFilter(String encoding, boolean forceRequestEncoding, boolean forceResponseEncoding) {
Assert.hasLength(encoding, "Encoding must not be empty");
this.encoding = encoding;
this.forceRequestEncoding = forceRequestEncoding;
this.forceResponseEncoding = forceResponseEncoding;
}
// 可以在构造函数执行之后设定字符集
public void setEncoding(@Nullable String encoding) {
this.encoding = encoding;
}
/**
* Return the configured encoding for requests and/or responses.
* @since 4.3
*/
@Nullable
public String getEncoding() {
return this.encoding;
}
// 可以在构造函数执行之后指定 forceRequestEncoding/forceResponseEncoding都为forceEncoding
public void setForceEncoding(boolean forceEncoding) {
this.forceRequestEncoding = forceEncoding;
this.forceResponseEncoding = forceEncoding;
}
// 可以在构造函数执行之后指定 forceRequestEncoding
public void setForceRequestEncoding(boolean forceRequestEncoding) {
this.forceRequestEncoding = forceRequestEncoding;
}
/**
* Return whether the encoding should be forced on requests.
* @since 4.3
*/
public boolean isForceRequestEncoding() {
return this.forceRequestEncoding;
}
// 可以在构造函数执行之后指定 forceResponseEncoding
public void setForceResponseEncoding(boolean forceResponseEncoding) {
this.forceResponseEncoding = forceResponseEncoding;
}
/**
* Return whether the encoding should be forced on responses.
* @since 4.3
*/
public boolean isForceResponseEncoding() {
return this.forceResponseEncoding;
}
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 获取指定给该过滤器使用的字符集
String encoding = getEncoding();
if (encoding != null) {
// 如果指定了字符集
if (isForceRequestEncoding() || request.getCharacterEncoding() == null) {
// 如果指定了字符集
// 并且 forceRequestEncoding 或者 请求没有字符集信息,则请求使用指定的字符集
request.setCharacterEncoding(encoding);
}
if (isForceResponseEncoding()) {
// 如果指定了字符集
// 并且 forceResponseEncoding , 则响应使用指定的字符集
response.setCharacterEncoding(encoding);
}
}
filterChain.doFilter(request, response);
}
}