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的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 舌头有牙齿印怎么回事?
- 下一篇: 【vcenter】redhat虚拟机时间