【问题标题】:o:graphicImage caching possible?o:graphicImage 缓存可能吗?
【发布时间】:2020-04-23 19:18:55
【问题描述】:

在我的顶部栏中,我有一个 <o:graphicImage> 来显示来自我的用户的图片。

<o:graphicImage dataURI="true" height="32" width="32" styleClass="img-circle"
    value="#{employeeProfileMenuPictureRequestController.getPicture_32_32(loginBean.currentEmployee)}" 
    lastModified="#{employeeProfileMenuPictureRequestController.lastUpdate}" />

我的后端 bean 如下:

@GraphicImageBean
public class EmployeeProfileMenuPictureRequestController implements Serializable {

    private Date lastUpdate = new Date();

    public byte[] getPicture_32_32(Employee employee) throws StorageAttachmentNotFoundException, IOException {
        try {

            String path = employeeProfilePictureService.findProfileImageByEmployee(employee, FileSizeType.SIZE_32_32.toString());

            if (employee == null || path == null || path.isEmpty()) {
                return Utils.toByteArray(Faces.getResourceAsStream("/resources/images/no-photo-icon.png"));
            }

            Path fileLocation = Paths.get(path);
            byte[] data = Files.readAllBytes(fileLocation);
            LOGGER.info("END getPicture_32_32");
            return data;
        catch (Exception e) {
            LOGGER.error(ExceptionUtils.getFullStackTrace(e));
        }

        return Utils.toByteArray(Faces.getResourceAsStream("/resources/images/no-photo-icon.png"));
    }

    public Date getLastUpdate() {
        return lastUpdate;
    }
}

不幸的是,每个页面请求/页面导航都会调用getPicture_32_32(Employee)。这意味着它也是每次对数据库的请求,这需要时间。

我已经尝试将lastModified 添加到&lt;o:graphicImage&gt;,但每次页面请求时也会调用该函数。

谁能帮我解决这个问题?

【问题讨论】:

  • 如果 lastUpdate 始终是 new Date(l 则说明它没有被缓存的资源
  • 但我使用的是@GraphicImageBean?这类似于 SessionScoped?那我该如何解决呢?
  • 为什么要使用dataURI?你能用纯html缓存那些吗?不要以为你可以。它们嵌入在页面中...... Snafu......
  • 试试 PrimeFaces p:cache
  • 如果我将 dataURI 切换为“false”,那么我得到:请求 /javax.faces.resource/EmployeeProfileMenuPictureRequestController_getPicture_32_32.jsf: javax.servlet.ServletException: 参数类型不匹配

标签: jsf caching omnifaces graphicimage


【解决方案1】:

根据&lt;o:graphicImage&gt; documentation:

数据 URI

[...]

建议将此方法用于“永久”和/或“大”图像,因为它不会为浏览器提供任何缓存图像的机会以供重复使用, ~10KB 通常是最大值甚至更少,所以如果同一页面上有更多这样的图像。

所以,它根本不支持缓存。技术原因是它基本上将图像的全部内容嵌入到 HTML 输出中。它不会在图像中嵌入 URL。 lastModified 基本上被忽略了。我可能应该更好地记录这一点。至少,您应该绝对删除 dataURI 属性。它仅对例如有用上传图片的预览。

还有,

图像流

[...]

如果属性是带参数的方法表达式,则每个参数都将转换为字符串 HTTP 请求参数,并使用类注册的转换器(可通过Application.createConverter(Class) 获得)返回实际对象。因此,像Long 这样的大多数标准类型已经被隐式支持。 如果您出于某种原因需要提供自定义对象作为参数,您需要自己通过@FacesConverter(forClass) 显式注册一个转换器

因此,因为您的方法采用Employee 参数,所以您基本上需要有一个@FacesConverter(forClass=Employee.class) 以便JSF 可以自动将其与String 转换。如何创建转换器可以在这里找到:Conversion Error setting value for 'null Converter' - Why do I need a Converter in JSF?

你应该得到这样的结果:

@FacesConverter(forClass=Employee.class)
public class EmployeeConverter implements Converter {

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
        // Write code here which converts Employee to its unique String representation.
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
        // Write code here which coverts the Employee unique String representation
        // as created in above method back to the original Employee object.
    }

}

另一种方法是调整您的 getPicture_32_32() 方法以将员工 ID 用作例如Long 而不是员工。那么你就不需要自定义转换器了。 JSF 已经内置了Long 的转换器。

public byte[] getPicture_32_32(Long employeeId) {
    // ...
}
<o:graphicImage
    value="#{employeeProfileMenuPictureRequestController.getPicture_32_32(loginBean.currentEmployee.id)}" />

回到缓存,文档是这样说的:

缓存

[...]

如果未指定,则将使用 Mojarra 特定上下文参数 com.sun.faces.defaultResourceMaxAge 或 MyFaces 特定上下文参数 org.apache.myfaces.RESOURCE_MAX_TIME_EXPIRES 中设置的“默认资源最大年龄”,否则将假定默认值为 1 周

因此,当您没有资源年龄设置时,默认情况下它已经缓存了 1 周。因此,lastModified 是可选的,仅当您在实际更改映像时实际跟踪同一数据库或文件系统中的时间戳时才有用。然后,您应该真正使用它来获得最佳缓存。 “随机”日期绝对不是正确的方法。

【讨论】:

  • 谢谢...还有一个问题,我不明白...我正在使用@GraphicImageBean(但也可以使用@ApplicationScoped)...所以私人日期最后更新 = 新日期();这是每个员工吗?每次员工更改个人资料图片时,我都必须设置一个新日期,对吗?
  • 你需要使用图片本身的最后修改日期,是的。
猜你喜欢
  • 2013-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多