PrimeFaces 6.0不会在客户端缓存图像

Tin*_*iny 8 jsf caching primefaces graphicimage

给定<p:dataTable>其中一列中的渲染图像.

<p:dataTable id="dataTable" var="row" value="#{bean}"
             lazy="true"
             skipChildren="true">

    <p:column headerText="Image">
        <p:cellEditor>
            <f:facet name="output">
                <p:graphicImage value="#{imageBean.image}" stream="true" cache="true">
                    <f:param name="id" value="#{row.id}"/>
                    <f:param name="width" value="100"/>
                    <f:param name="height" value="100"/>
                </p:graphicImage>
            </f:facet>

            <f:facet name="input">
                <p:graphicImage value="#{imageBean.image}" stream="true" cache="true">
                    <f:param name="id" value="#{row.id}"/>
                    <f:param name="width" value="100"/>
                    <f:param name="height" value="100"/>
                </p:graphicImage>

                <!-- <p:overlayPanel> here for file upload -->
            </f:facet>
        </p:cellEditor>
    </p:column>

    <p:column headerText="Edit">
        <p:rowEditor/>
    </p:column>
</p:dataTable>
Run Code Online (Sandbox Code Playgroud)

数据表可以在需要时包含其他必要的常用属性和列.

当此表(Ajaxically)更新时,所有图像都从数据库(或磁盘文件系统,如果使用)中获取,就像它们根本没有被浏览器缓存一样,即使cache显式设置为true(这是默认值).这在PrimeFaces 5.3决赛中表现良好.

迁移指南没有说明它,但显然有些内容已经改变了缓存<p:graphicImage>.

有什么建议来解决这个问题吗?

在上面的示例中,例如,如果表包含5行中的5个图像,则每次对<p:dataTable>(默认为当前行的内联行编辑除外)进行的更新都将查询数据库10次,这不应该作为获取特别是来自数据库的图像非常昂贵.


使用PrimeFaces 6.0 final(在WildFly 10.0.0 final上运行)的请求/响应头,当向服务器发出初始请求以提供图像时(不起作用 - 图像不被缓存).

General
    Request URL:https://localhost:8443/ContextRoot/javax.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=6.0&pfdrid=aed903cc-daba-4822-a62b-888b9a0ef2ac&pfdrt=sc&id=14&width=100&height=100&pfdrid_c=true
    Request Method:GET
    Status Code:200 OK
    Remote Address:127.0.0.1:8443
Response Headers
    Cache-Control:max-age=29030400
    Connection:keep-alive
    Date:Sat, 23 Jul 2016 06:59:54 GMT
    Expires:Sun, 23 Jul 2017 06:59:54 GMT
    Server:WildFly/10
    Transfer-Encoding:chunked
    X-Powered-By:Undertow/1
Request Headers
    Accept:image/webp,image/*,*/*;q=0.8
    Accept-Encoding:gzip, deflate, sdch
    Accept-Language:en-US,en;q=0.8
    Connection:keep-alive
    Cookie:JSESSIONID=4AoRGa1IAPTB4KssnikbO9uUetcQpMupli8BkGga.om-f6b0ea3ad206; __utma=111872281.616526714.1454485589.1468749319.1468751735.4; __utmz=111872281.1454485589.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
    Host:localhost:8443
    Referer:https://localhost:8443/ContextRoot/admin/Brand
    User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
Query String Parameters
    ln:primefaces
    v:6.0
    pfdrid:aed903cc-daba-4822-a62b-888b9a0ef2ac
    pfdrt:sc
    id:14
    width:100
    height:100
    pfdrid_c:true
Run Code Online (Sandbox Code Playgroud)

使用PrimeFaces 5.3 final(在GlassFish 4.1上运行)的请求/响应标头,当向服务器发出初始请求以提供图像时(按预期工作 - 图像被缓存).

General
    Request URL:https://localhost:8181/ContextRoot/javax.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=5.3&pfdrid=aAPHlxcQ2lcqfvzacYoCC6iUxLU1VVFp&pfdrt=sc&id=11&width=100&height=100&pfdrid_c=true
    Request Method:GET
    Status Code:200 OK
    Remote Address:127.0.0.1:8181
Response Headers
    Cache-Control:max-age=29030400
    Date:Sat, 23 Jul 2016 07:15:03 GMT
    Expires:Sun, 23 Jul 2017 07:15:04 GMT
    Pragma:No-cache
    Server:GlassFish Server Open Source Edition  4.1
    Transfer-Encoding:chunked
    X-Powered-By:Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition  4.1  Java/Oracle Corporation/1.8)
Request Headers
    Accept:image/webp,image/*,*/*;q=0.8
    Accept-Encoding:gzip, deflate, sdch
    Accept-Language:en-US,en;q=0.8
    Connection:keep-alive
    Cookie:JSESSIONID=69b5070218cfe0fc6eaac2141c13; __utma=111872281.616526714.1454485589.1468749319.1468751735.4; __utmz=111872281.1454485589.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)
    Host:localhost:8181
    Referer:https://localhost:8181/ContextRoot/admin/Brand
    User-Agent:Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36
Query String Parameters
    ln:primefaces
    v:5.3
    pfdrid:aAPHlxcQ2lcqfvzacYoCC6iUxLU1VVFp
    pfdrt:sc
    id:11
    width:100
    height:100
    pfdrid_c:true
Run Code Online (Sandbox Code Playgroud)

Bal*_*usC 10

标题看起来不错.这表明查询字符串参数中的某些内容会从请求更改为请求.这也将被解释为一种全新的资源,因此即使基本URI(URL查询字符串分隔符之前的部分?)完全相同,也会破坏缓存.

事实上,PrimeFaces 6.0改变了pfdrid生成查询字符串参数的方式.它已成为一个完全随机的UUID,每次<img src>呈现HTML时都会发生变化.另请参见PF 6.0源代码的第59行.在PrimeFaces 5.3中,它基于EL表达式字符串进行加密,因此只要EL表达式字符串相同,就可以保证在请求之间保持相同.另见PF 5.3源代码的第53行.

这一变化是由Cagatay 引入的,没有提及发行票.所以仍然不清楚为什么要做这个改变.但毕竟它不再为客户提供缓存动态内容的机会,从而实际上会降低两端的性能.这绝对值得在PrimeFaces发行,所以我创建了一个:问题1765.

除了攻击PrimeFaces源代码之外,我没有看到解决这个问题的干净方法.你最好的选择是用一个"普通的servilla servlet" 代替<p:graphicImage>一个<h:graphicImage>,或者你碰巧使用JSF实用程序库OmniFaces,然后<o:graphicImage>用一个简单的bean.这些方法已在此相关问答中详述:在数据库中将图像显示为byte [],作为JSF页面中的图形图像.


更新:根据问题1765,它已针对PrimeFaces 6.1进行了修复.