【问题标题】:When I used CookieLocaleResolver, I can set invalid cookie to crash spring web application当我使用 CookieLocaleResolver 时,我可以设置无效的 cookie 以使 Spring Web 应用程序崩溃
【发布时间】:2015-01-20 08:12:48
【问题描述】:

在 web.xml 中:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
    <display-name>Spring MVC Servlet</display-name>
    <servlet-name>spring-dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

在 spring-dispatcher-servlet.xml 中

<context:component-scan base-package="lei.spring.mvc.controller" />

在 applicationContext.xml 中

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" p:cookieName="clientLang" />

我将clientLang cookie的内容设置为en-CA后,spring只向我的浏览器返回如下异常:

java.lang.IllegalArgumentException: Locale part "en-CA" contains invalid characters
at org.springframework.util.StringUtils.validateLocalePart(StringUtils.java:710)
at org.springframework.util.StringUtils.parseLocaleString(StringUtils.java:690)
at org.springframework.web.servlet.i18n.CookieLocaleResolver.parseLocaleCookieIfNecessary(CookieLocaleResolver.java:164)
at org.springframework.web.servlet.i18n.CookieLocaleResolver.resolveLocaleContext(CookieLocaleResolver.java:136)
at org.springframework.web.servlet.DispatcherServlet.buildLocaleContext(DispatcherServlet.java:1043)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:955)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)

然后我尝试创建自己的 MyCookieLocaleResolver 类来捕获所有异常并返回默认的 Locale 实例:

public class MyCookieLocaleResolver extends CookieLocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
    try {
        return super.resolveLocale(request);
    } catch (Exception exception) {
        return new Locale.Builder().setLanguage("en").setRegion("CA").build();
    }
}
}

将 applicationContext.xml 更改为:

<bean id="localeResolver" class="package.MyCookieLocaleResolver" p:cookieName="clientLang" />

但是 spring 仍然向我的浏览器返回相同的异常。我阅读了 DispatcherServlet 的代码。似乎 this.localeResolver 实例为空,它不是来自 localeResolver 实例。它总是使用 CookieLocaleResolver 实例。如何将 localeResolver 实例设置为 DispatcherServlet?

protected LocaleContext buildLocaleContext(final HttpServletRequest request) {

    if (this.localeResolver instanceof LocaleContextResolver) {
        return ((LocaleContextResolver) this.localeResolver).resolveLocaleContext(request);
    }
    else {
        return new LocaleContext() {
            @Override
            public Locale getLocale() {
                return localeResolver.resolveLocale(request);
            }
        };
    }
}

【问题讨论】:

    标签: java spring spring-mvc cookies


    【解决方案1】:

    尝试仅使用“en”作为默认语言环境:

    <bean id="localeResolver"
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
        <property name="defaultLocale" value="en" />
        <property name="cookieName" value="clientLang" />
        <property name="cookieMaxAge" value="31556926" />
    </bean>
    

    【讨论】:

      【解决方案2】:

      我重写了两个方法后,效果很好:

      public class MyCookieLocaleResolver extends CookieLocaleResolver {
      @Override
      public Locale resolveLocale(HttpServletRequest request) {
          try {
              return super.resolveLocale(request);
          } catch (Exception exception) {
              return Locale.forLanguageTag("en-CA");
          }
      }
      
      @Override
      public LocaleContext resolveLocaleContext(final HttpServletRequest request) {
          try {
              return super.resolveLocaleContext(request);
          } catch (Exception exception) {
              return new LocaleContext() {
                  @Override
                  public Locale getLocale() {
                      return Locale.forLanguageTag("en-CA");
                  }
              };
          }
      }
      

      }

      【讨论】:

        【解决方案3】:

        从 4.3 版本开始,有一个新参数 languageTagCompliant 可以启用语言标签解析

        CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
        cookieLocaleResolver.setLanguageTagCompliant(true);
        

        【讨论】:

        • 在 Spring 5.2.1 上使用 setLanguageTagCompliant 时出现同样的错误。
        猜你喜欢
        • 1970-01-01
        • 2022-08-03
        • 1970-01-01
        • 2016-04-02
        • 2019-10-12
        • 2016-06-20
        • 2020-02-07
        • 1970-01-01
        • 2016-03-07
        相关资源
        最近更新 更多