spring mvc字符编码过滤器 CharacterEncodingFilter ,添加例外url
前言
- spring 4.3.4.RELEASE
- CharacterEncodingFilter : Spring MVC 提供的字符集過濾器,用于處理項目中的亂碼問題
- 項目比較老,大部分url使用的是GBK編碼,少量url使用UTF-8編碼。
- 需要對 CharacterEncodingFilter 設置例外。即,少量url不要進行 CharacterEncodingFilter 過濾。
CharacterEncodingFilter設置
<filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>GBK</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>url-pattern很霸氣,過濾所有。
forceEncoding更霸氣,強制編碼格式為GBK。
為什么這么設置不說了(很顯然這樣讓charset為UTF-8的JS很受傷),就說怎么辦吧。
受傷的JS
<script type="text/javascript" language="javascript" src="../codebase/laydate/laydate.js" charset="UTF-8"></script>CharacterEncodingFilter添加例外
方法1(推薦):filter-mapping添加例外
嗯~,filter-mapping添加例外是個好辦法。
<!-- 解決編碼問題過濾器 --><filter><filter-name>characterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>GBK</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><!-- CharacterEncodingFilter過濾器添加例外 --><filter><filter-name>characterEncodingFilter_utf8</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_utf8</filter-name><url-pattern>/codebase/laydate/laydate.js</url-pattern></filter-mapping>方法2:告知CharacterEncodingFilter不用再處理了
根據CharacterEncodingFilter代碼顯示,在request的Attribute中,增加名為filter-name.FILTERED,值為TRUE的Attribute時,會跳過過濾器。
本文中需要增加名為characterEncodingFilter.FILTERED的Attribute。
增加名為characterEncodingFilter.FILTERED的Attribute的方法則是:在characterEncodingFilter執行前,再增加一個Filter。該Filter向request增加名為characterEncodingFilter.FILTERED的Attribute。(該Filter需要自己寫,此處暫不提供)
CharacterEncodingFilter的相關代碼如下:
CharacterEncodingFilter的相關代碼:
public class CharacterEncodingFilter extends OncePerRequestFilter {... }OncePerRequestFilter的相關代碼:
public abstract class OncePerRequestFilter extends GenericFilterBean {/*** Suffix that gets appended to the filter name for the* "already filtered" request attribute.* @see #getAlreadyFilteredAttributeName*/public static final String ALREADY_FILTERED_SUFFIX = ".FILTERED";/*** This {@code doFilter} implementation stores a request attribute for* "already filtered", proceeding without filtering again if the* attribute is already there.* @see #getAlreadyFilteredAttributeName* @see #shouldNotFilter* @see #doFilterInternal*/@Overridepublic final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)throws ServletException, IOException {if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {throw new ServletException("OncePerRequestFilter just supports HTTP requests");}HttpServletRequest httpRequest = (HttpServletRequest) request;HttpServletResponse httpResponse = (HttpServletResponse) response;String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();boolean hasAlreadyFilteredAttribute = request.getAttribute(alreadyFilteredAttributeName) != null;if (hasAlreadyFilteredAttribute || skipDispatch(httpRequest) || shouldNotFilter(httpRequest)) {// Proceed without invoking this filter...filterChain.doFilter(request, response);}else {// Do invoke this filter...request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);try {doFilterInternal(httpRequest, httpResponse, filterChain);}finally {// Remove the "already filtered" request attribute for this request.request.removeAttribute(alreadyFilteredAttributeName);}}}/*** Return the name of the request attribute that identifies that a request* is already filtered.* <p>The default implementation takes the configured name of the concrete filter* instance and appends ".FILTERED". If the filter is not fully initialized,* it falls back to its class name.* @see #getFilterName* @see #ALREADY_FILTERED_SUFFIX*/protected String getAlreadyFilteredAttributeName() {String name = getFilterName();if (name == null) {name = getClass().getName();}return name + ALREADY_FILTERED_SUFFIX;}... }GenericFilterBean的相關代碼:
public abstract class GenericFilterBean implements Filter, BeanNameAware, EnvironmentAware,EnvironmentCapable, ServletContextAware, InitializingBean, DisposableBean {/*** Make the name of this filter available to subclasses.* Analogous to GenericServlet's {@code getServletName()}.* <p>Takes the FilterConfig's filter name by default.* If initialized as bean in a Spring application context,* it falls back to the bean name as defined in the bean factory.* @return the filter name, or {@code null} if none available* @see javax.servlet.GenericServlet#getServletName()* @see javax.servlet.FilterConfig#getFilterName()* @see #setBeanName*/@Nullableprotected String getFilterName() {return (this.filterConfig != null ? this.filterConfig.getFilterName() : this.beanName);}... } 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的spring mvc字符编码过滤器 CharacterEncodingFilter ,添加例外url的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 舌头有牙齿印怎么回事?
- 下一篇: zookeeper启动占用8080端口