在我的顶部栏中,我有一个<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添加到<o:graphicImage>中,但每次页面请求时也会调用该函数。
有人能帮我解决这个问题吗?
发布于 2020-04-24 17:47:31
根据 documentation:的说法
数据URI
..。
然而,对于“永久的”和/或“大的”图像,不建议使用这种方法,因为不会为浏览器提供任何缓存图像以供重用的机会,如果在同一页面上有更多这样的图像,~10KB通常是最大值。
因此,它根本不支持缓存。技术原因是它基本上将图像的全部内容嵌入到HTML输出中。它不会嵌入图像的URL。lastModified基本上被忽略了。我应该更好地记录这一点。至少,您应该完全删除dataURI属性。它只适用于预览上传的图片。
和,
图像流
..。
如果属性是一个带有参数的方法表达式,那么这些参数中的每个参数都将被转换为string 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而不是employee。那么你就不需要一个自定义的转换器了。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是可选的,并且仅当您实际跟踪同一数据库或文件系统中的时间戳时才有用。然后,您应该真正使用它来实现最优的缓存。“随机”的日期绝对不是正确的方式。
https://stackoverflow.com/questions/61395308
复制相似问题