1

我需要在我的 Web 应用程序中强制使用 HTTPS,所以我在 web.xml 配置中做了以下两件事:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>*</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

<session-config>
    <session-timeout>10</session-timeout>
    <cookie-config>
        <http-only>true</http-only>
        <secure>true</secure>
    </cookie-config>
    <tracking-mode>COOKIE</tracking-mode>
</session-config>

当我在 glassfish 5(应该运行 webapp 的容器)上部署 webapp 时,出现一系列错误,就好像应用程序在 servlet 过滤器链期间进入了循环一样。

我可以识别的例外是:

更新堆栈如下

[glassfish 5.0] [SEVERE] [] [org.glassfish.grizzly.http2.Http2ServerFilter] [tid: _ThreadID=45 _ThreadName=http-listener-2(2)] [timeMillis: 1519314445367] [levelValue: 1000] [[
  Unable to push resource identified by path [/demat/svz]]]

[glassfish 5.0] [SEVERE] [] [org.glassfish.grizzly.http2.Http2ServerFilter] [tid: _ThreadID=48 _ThreadName=http-listener-2(5)] [timeMillis: 1519314445367] [levelValue: 1000] [[
  Unable to push resource identified by path [/demat/javax.faces.resource/core.js.jsf?ln=primefaces&v=6.1.2.NLC]]]

[glassfish 5.0] [SEVERE] [] [org.glassfish.grizzly.http2.Http2ServerFilter] [tid: _ThreadID=45 _ThreadName=http-listener-2(2)] [timeMillis: 1519314445367] [levelValue: 1000] [[


[glassfish 5.0] [SEVERE] [] [org.glassfish.grizzly.http2.Http2ServerFilter] [tid: _ThreadID=46 _ThreadName=http-listener-2(2)] [timeMillis: 1519144903315] [levelValue: 1000] [[

org.glassfish.grizzly.http2.Http2StreamException streamId=4474 errorCode=REFUSED_STREAM
    at org.glassfish.grizzly.http2.Http2Session.openStream(Http2Session.java:1116)
    at org.glassfish.grizzly.http2.Http2ServerFilter.doPush(Http2ServerFilter.java:994)
    at org.glassfish.grizzly.http2.Http2ServerFilter.handleEvent(Http2ServerFilter.java:626)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$6.execute(ExecutorResolver.java:94)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.filterchain.FilterChainContext.notifyDownstream(FilterChainContext.java:952)
    at org.glassfish.grizzly.filterchain.FilterChainContext.notifyDownstream(FilterChainContext.java:934)
    at org.apache.catalina.core.ApplicationPushBuilder.push(ApplicationPushBuilder.java:367)
    at com.sun.faces.context.ExternalContextImpl.pushIfPossibleAndNecessary(ExternalContextImpl.java:704)
    at com.sun.faces.context.ExternalContextImpl.encodeResourceURL(ExternalContextImpl.java:662)
    at javax.faces.context.ExternalContextWrapper.encodeResourceURL(ExternalContextWrapper.java:164)
    at com.sun.faces.renderkit.html_basic.ScriptStyleBaseRenderer.encodeEnd(ScriptStyleBaseRenderer.java:246)
    at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:949)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1912)
    at com.sun.faces.renderkit.RenderKitUtils.renderJsfJsIfNecessary(RenderKitUtils.java:1203)
    at com.sun.faces.renderkit.html_basic.CommandLinkRenderer.encodeBegin(CommandLinkRenderer.java:117)
    at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:892)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1903)
    at javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:918)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:309)
    at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:114)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:918)
    at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:309)
    at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:114)
    at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:918)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1905)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908)


org.glassfish.grizzly.http.util.MimeHeaders$MaxHeaderCountExceededException: Illegal attempt to exceed the configured maximum number of headers: 100
    at org.glassfish.grizzly.http.util.MimeHeaders.createHeader(MimeHeaders.java:466) ~[nucleus-grizzly-all.jar:?]
    at org.glassfish.grizzly.http.util.MimeHeaders.addValue(MimeHeaders.java:507) ~[nucleus-grizzly-all.jar:?]
    at org.apache.catalina.core.ApplicationPushBuilder.<init>(ApplicationPushBuilder.java:222) ~[web-core.jar:?]
    at org.apache.catalina.connector.Request.newPushBuilder(Request.java:2609) ~[web-core.jar:?]
    at org.apache.catalina.connector.RequestFacade.newPushBuilder(RequestFacade.java:1167) ~[web-core.jar:?]
    at com.sun.faces.context.ExternalContextImpl.getPushBuilder(ExternalContextImpl.java:728) ~[javax.faces.jar:2.3.2]
    at com.sun.faces.context.ExternalContextImpl.pushIfPossibleAndNecessary(ExternalContextImpl.java:701) ~[javax.faces.jar:2.3.2]
    at com.sun.faces.context.ExternalContextImpl.encodeResourceURL(ExternalContextImpl.java:662) ~[javax.faces.jar:2.3.2]
    at com.sun.faces.el.ResourceELResolver.getValue(ResourceELResolver.java:143) ~[javax.faces.jar:2.3.2]
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:180) ~[javax.faces.jar:2.3.2]
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:208) ~[javax.faces.jar:2.3.2]
    at com.sun.el.parser.AstValue.getValue(AstValue.java:139) ~[javax.el.jar:3.0.1-b08]
    at com.sun.el.parser.AstValue.getValue(AstValue.java:203) ~[javax.el.jar:3.0.1-b08]
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:226) ~[javax.el.jar:3.0.1-b08]
    at org.jboss.weld.module.web.el.WeldValueExpression.getValue(WeldValueExpression.java:50) ~[weld-osgi-bundle.jar:3.0.0.Final]
    at com.sun.faces.application.resource.ResourceHelper$ELEvaluatingInputStream.evaluateExpressionIntoBuffer(ResourceHelper.java:832) ~[javax.faces.jar:2.3.2]
    at com.sun.faces.application.resource.ResourceHelper$ELEvaluatingInputStream.readExpressionIntoBufferAndEvaluateIntoBuffer(ResourceHelper.java:755) ~[javax.faces.jar:2.3.2]
    at com.sun.faces.application.resource.ResourceHelper$ELEvaluatingInputStream.read(ResourceHelper.java:719) ~[javax.faces.jar:2.3.2]
    at java.io.InputStream.read(InputStream.java:179) ~[?:1.8.0_121]
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) ~[?:1.8.0_121]
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:286) ~[?:1.8.0_121]
    at java.io.BufferedInputStream.read(BufferedInputStream.java:345) ~[?:1.8.0_121]
    at java.nio.channels.Channels$ReadableByteChannelImpl.read(Channels.java:385) ~[?:1.8.0_121]
    at com.sun.faces.application.resource.ResourceHandlerImpl.handleResourceRequest(ResourceHandlerImpl.java:345) ~[javax.faces.jar:2.3.2]
    at javax.faces.application.ResourceHandlerWrapper.handleResourceRequest(ResourceHandlerWrapper.java:178) ~[javax.faces.jar:2.3.2]
    at org.primefaces.application.resource.PrimeResourceHandler.handleResourceRequest(PrimeResourceHandler.java:87) ~[primefaces-6.1.2.SIA.jar:?]
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:667) ~[javax.faces.jar:2.3.2]
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1580) ~[web-core.jar:?]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:338) ~[web-core.jar:?]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[web-core.jar:?]
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:100) ~[primefaces-6.1.2.SIA.jar:?]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:250) ~[web-core.jar:?]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[web-core.jar:?]
4

2 回答 2

3

从 JSF 2.3 开始,当服务器和客户端都支持 HTTP/2 协议并且连接通过 SSL (HTTPS) 时,CSS/JS 资源将自动推送到服务器。您可以在堆栈跟踪的这一部分的类和方法名称中清楚地看到这一点:

at com.sun.faces.context.ExternalContextImpl.pushIfPossibleAndNecessary(ExternalContextImpl.java:704)
at com.sun.faces.context.ExternalContextImpl.encodeResourceURL(ExternalContextImpl.java:662)
at javax.faces.context.ExternalContextWrapper.encodeResourceURL(ExternalContextWrapper.java:164)
at com.sun.faces.renderkit.html_basic.ScriptStyleBaseRenderer.encodeEnd(ScriptStyleBaseRenderer.java:246)

但是,在您的特定情况下,有问题的 JSF 页面显然具有如此多的 CSS/JS 资源,以至于超过了服务器配置的 100 个响应标头条目的限制。

org.glassfish.grizzly.http.util.MimeHeaders$MaxHeaderCountExceededException:非法尝试超过配置的最大标头数:100

鉴于这些事实,有几种解决方案:

  1. 减少 CSS/JS 资源的数量。坦率地说,大约 100 个 CSS/JS 资源太疯狂了。如有必要,请考虑在OmniFacesCombinedResourceHandler的帮助下组合它们。
  2. 配置 GlassFish 以允许超过 100 个标头。这可以通过asadmin命令行完成。下面是一个将其增加到 200 的示例,并假设正在使用的 HTTP 侦听器的名称是http-listener-1(您也可以在管理控制台应用程序中找到它)。

    set configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.max-response-headers=200
    
  3. 通过以下特定于 Mojarra 的技巧显式禁用推送 CSS/JS 资源。

    @FacesConfig
    @ApplicationScoped
    public class Config {
    
        @Inject
        private FacesContext context;
    
        public void viewInitialized(@Observes @Initialized(ViewScoped.class) UIViewRoot view) {
            context.getAttributes().put("com.sun.faces.ExternalContextImpl.PUSH_SUPPORTED", false);
        }
    
    }
    

    这确实有点hacky,但那是因为没有明确支持通过例如web.xml上下文参数禁用它。请注意,@FacesConfig为了能够 , 这是必要@InjectFacesContext,并且在应用程序范围内只有一个注释就足够了。不然还是可以抢FacesContext#getCurrentInstance()的。

于 2018-02-20T18:52:55.240 回答
0

我通过禁用 HTTP/2 解决了这个问题。出于某种原因,推送到浏览器的资源数量并不重要,但只要我保持启用 HTTP/2,它就会产生上述错误(问题中提到的那些)。

要禁用 HTTP/2,请在 asadmin 中执行以下命令:

> asadmin set server.network-config.protocols.protocol.http-listener-2.http.http2-enabled=false

或者在你的domain.xml

<protocol name="http-listener-2" security-enabled="true">
  <http http2-enabled="false" max-connections="250" compression="on" default-virtual-server="server">
    <file-cache></file-cache>
  </http>
      <ssl classname="com.sun.enterprise.security.ssl.GlassfishSSLImpl" cert-nickname="s1as"></ssl>
</protocol>
于 2018-02-22T11:23:18.293 回答