java.lang.IllegalStateException在集群环境中

时间:2016-08-04 10:14:54

标签: java spring spring-security hazelcast spring-session

我有春季,春季安全,春季会议与淡褐色的网络应用程序。 它在集群环境中运行。 我不时在日志中看到此异常,但无法在本地重现它。 它看起来像一些itercetptor或过滤器无法正常工作。 有什么建议如何找到问题的原因?

java.lang.IllegalStateException: Cannot forward after response has been committed
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:328) [catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:318) [catalina.jar:8.0.35]
at org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler.handleRequest(DefaultServletHttpRequestHandler.java:122) ~[spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51) ~[spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) [servlet-api.jar:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) [catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) [catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:720) [catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:584) [catalina.jar:8.0.35]
at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:523) [catalina.jar:8.0.35]
at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:436) [catalina.jar:8.0.35]
at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:379) [catalina.jar:8.0.35]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:176) [catalina.jar:8.0.35]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [catalina.jar:8.0.35]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) [catalina.jar:8.0.35]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) [catalina.jar:8.0.35]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) [catalina.jar:8.0.35]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099) [tomcat-coyote.jar:8.0.35]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672) [tomcat-coyote.jar:8.0.35]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520) [tomcat-coyote.jar:8.0.35]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476) [tomcat-coyote.jar:8.0.35]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_91]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.0.35]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91]

的web.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>xxxx</display-name>
  <description>xxxx</description>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <listener>
    <listener-class>ch.qos.logback.classic.selector.servlet.ContextDetachingSCL</listener-class>
  </listener>

  <context-param>
    <param-name>defaultHtmlEscape</param-name>
    <param-value>true</param-value>
  </context-param>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
  </context-param>
  <context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>com.xxxxx.services.authentication.xxxxApplicationContextInitializer</param-value>
  </context-param>
  <filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>  
  <filter>
    <filter-name>LoggerContextFilter</filter-name>
    <filter-class>ch.qos.logback.classic.selector.servlet.LoggerContextFilter</filter-class>
  </filter>
  <filter>
    <filter-name>PageExpiryFilter</filter-name>
    <filter-class>com.xxxxx.web.filters.PageExpiryFilter</filter-class>
  </filter>
  <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>
    <filter-name>HttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
  </filter>
  <filter>
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
  </filter>
  <filter>
    <filter-name>sessionIpAddressSecurityFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>LoggerContextFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <filter-mapping>
    <filter-name>PageExpiryFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>HttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
    <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter-mapping>
    <filter-name>sessionIpAddressSecurityFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <servlet>
    <servlet-name>yyyy</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>WEB-INF/spring/webmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>yyyy</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>120</session-timeout>
  </session-config>
  <error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/error-page</location>
  </error-page>
  <error-page>
    <error-code>404</error-code>
    <location>/resourceNotFound</location>
  </error-page>
  <error-page>
    <error-code>405</error-code>
    <location>/resourceNotFound</location>
  </error-page>
  <error-page>
    <error-code>400</error-code>
    <location>/resourceNotFound</location>
  </error-page>
  <error-page>
    <error-code>403</error-code>
    <location>/notAuthorized</location>
  </error-page>
  <error-page>
    <error-code>401</error-code>
    <location>/notAuthorized</location>
  </error-page>
  <error-page>
    <error-code>500</error-code>
    <location>/serverError</location>
  </error-page>
  <error-page>
    <error-code>503</error-code>
    <location>/serverError</location>
  </error-page>
  <error-page>
    <error-code>504</error-code>
    <location>/serverError</location>
  </error-page>
  <jsp-config>
    <taglib>
      <taglib-uri>http://xx.xx.xxx.com/tlds/functions</taglib-uri>
      <taglib-location>/WEB-INF/tags/review.tld</taglib-location>
    </taglib>
  </jsp-config>
</web-app>

PageExpiryFilter:

public class PageExpiryFilter implements javax.servlet.Filter {
private static final int HOUR_TO_MINUTE = 60;
private static final int DAY_TO_MINUTE = 60 * 24;
private static final int MONTH_TO_MINUTE = 60 * 24 * 30;
private static final int WEEK_TO_MINUTE = 60 * 24 * 7;

private PageExpiryFilterPropertiesLoader loader = new PageExpiryFilterPropertiesLoader();

private final Pattern pattern = Pattern.compile("^(\\d+)(m|M|h|d|w)$");
private final SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");

private Map<String, Integer> pathRegex;

@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
    if (response instanceof HttpServletResponse && request instanceof HttpServletRequest) {
        final HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        final String path = httpServletRequest.getRequestURI();
        final HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        setResponseHeader(path, httpServletResponse);
    }

    chain.doFilter(request, response);
}

private void setResponseHeader(final String path, final HttpServletResponse httpServletResponse) {
    String expiryDate;
    for (final String regex : pathRegex.keySet()) {
        if (path.matches(regex)) {
            final Integer age = pathRegex.get(regex);
            expiryDate = createExpiryDate(age);
            httpServletResponse.setHeader("Expires", expiryDate);
        }
    }
}

private String createExpiryDate(final Integer age) {
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.MINUTE, age);
    return dateFormat.format(calendar.getTime());
}

@Override
public void init(final FilterConfig filterConfig) throws ServletException {
    dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
    pathRegex = new LinkedHashMap<String, Integer>();
    Properties properties = loader.loadProperties("/expires.properties");
    populatePathRegex(properties);
}

private void populatePathRegex(final Properties properties) {
    for (Entry<Object, Object> property : properties.entrySet()) {
        Integer expirationInMinutes = getExpirationInMinutes(((String) property.getValue()).trim());
        pathRegex.put((String) property.getKey(), expirationInMinutes);
    }
}

private Integer getExpirationInMinutes(final String value) {
    Integer minutes = 0;
    if (value != null && value.length() != 0) {
        final Matcher matcher = pattern.matcher(value);
        if (matcher.matches()) {
            final int val = Integer.parseInt(matcher.group(1));
            final String denomination = matcher.group(2);
            minutes = calculateMinutes(val, denomination);
        } else {
            throw new IllegalArgumentException("Invalid pattern '" + value + "'" + " for '" + value
                    + "'. Valid patterns are '2m' for 2 minutes, '10h' for 10 hours, '1d' for 1 day, '1w' for 1 week, '1M' for 1 month");
        }
    }
    return minutes;
}

private Integer calculateMinutes(final int val, final String denomination) {
    int factor;
    if ("m".equals(denomination)) {
        factor = 1;
    } else if ("h".equals(denomination)) {
        factor = HOUR_TO_MINUTE;
    } else if ("d".equals(denomination)) {
        factor = DAY_TO_MINUTE;
    } else if ("M".equals(denomination)) {
        factor = MONTH_TO_MINUTE;
    } else {
        factor = WEEK_TO_MINUTE;
    }
    return val * factor;
}

public void setLoader(final PageExpiryFilterPropertiesLoader loader) {
    this.loader = loader;
}

@Override
public void destroy() {
}

}

0 个答案:

没有答案