在Spring mvc框架中是如何解決從頁面傳來的字符串的編碼問題的呢?
下面我們來看看Spring框架給我們提供過濾器CharacterEncodingFilter。
web.xml 中 添加如下配置:
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- 字符編碼 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!-- 是否強制所有請求都使用該字符編碼 -->
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
spring mvc 內部提供了CharacterEncodingFilter過濾器,該過濾器有兩個參數encoding和forceEncoding。
- encoding
設置請求響應的字符編碼。(請求的數據使用encoding編碼解析,使用encoding編碼進行響應的數據) - forceEncoding
forceEncoding=true 強制所有的請求響應都使用encoding編碼。
forceEncoding=false 如果請求頭中包含charset,則使用chartset編碼,否則使用encoding編碼。
CharacterEncodingFilter 源碼分析
public class CharacterEncodingFilter extends OncePerRequestFilter {
private String encoding;
private boolean forceRequestEncoding = false;
private boolean forceResponseEncoding = false;
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public void setForceEncoding(boolean forceEncoding) {
this.forceRequestEncoding = forceEncoding;
this.forceResponseEncoding = forceEncoding;
}
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String encoding = getEncoding();
if (encoding != null) {
if (isForceRequestEncoding() || request.getCharacterEncoding() == null) {
request.setCharacterEncoding(encoding);
}
if (isForceResponseEncoding()) {
response.setCharacterEncoding(encoding);
}
}
filterChain.doFilter(request, response);
}
......
}
CharacterEncodingFilter 中包含 三個屬性 encoding、forceRequestEncoding、forceResponseEncoding。
- encoding:字符編碼類型
- forceRequestEncoding:request 是否強制使用encoding編碼
- forceResponseEncoding:response 是否強制使用encoding編碼
只要過濾器中配置了forceEncoding 屬性,則forceRequestEncoding和forceResponseEncoding 則保持一致,都使用forceEncoding的值。
doFilterInternal() 方法
該方法是過濾器的核心方法。
如果forceRequestEncoding=true,和forceResponseEncoding=true,則request和response都是用配置的encoding。
如果forceRequestEncoding=false, 則判斷request.getCharacterEncoding()是否有值,如果有值則使用客戶端傳過來的編碼(例如:charset=utf-8)
request.getCharacterEncoding() 解析
request中獲取encoding,追蹤org.apache.coyoteRequest.java類中getCharacterEncoding() 方法。
getContentType() 方法
從代碼中發現,contentType 就是從http請求頭中獲取 content-type屬性。
判斷 content-type 中是否包含charset屬性。如果存在則解析charset的屬性值,并返回。
想了解更多精彩內容請關注我的公眾號