java - 如何确保目录中的图像在更改后刷新?

标签 java html spring thymeleaf

我目前正在使用 Spring 和 Thymeleaf 创建一个 Java Web 应用程序,以使用 AES 加密用户提供的图像并输出加扰版本。但是,当我将图像保存到文件后尝试显示图像时,它似乎尚未更新,并且出现文件不存在的错误。然而,当我检查我的目录时,它显然已经存在了。我对 Thymeleaf 和 Spring 还很陌生。

我尝试使用 Thread.sleep 来加载图像。不幸的是它没有改变任何东西。我将图像存储在静态文件夹中。

我的Java代码如下:

String path = new File("src/main/resources/static").getAbsolutePath();
File outputFile = new File(path + "/output.jpg");
try {
  outputFile.createNewFile();
} catch (IOException e) {
  e.printStackTrace();
  System.out.println("FILE ALREADY EXISTS");
}

try {
  ImageIO.write(outputImage, "jpg", outputFile);
} catch (IOException e) {
  e.printStackTrace();
}

model.addAttribute("image", "output.jpg");

我的相关 HTML 代码如下所示:

<img th:src="${image}"/>

如果我再次传入图像,它会显示该图像,但如果我传入另一个图像,它会显示第一个图像。任何帮助将不胜感激。

最佳答案

您的浏览器可能会缓存该图像(将其存储在本地以防止将来再次下载)。您可以通过打开浏览器调试器 (F12) 轻松验证这一事实,并找到禁用缓存的选项。有多种方法可以通过编程解决此问题:

<小时/>

最简单的解决方案是每次更改文件时重命名图像,并使用这个唯一的文件名提供 URL。

File outputFile = new File(path + "/output-" + LocalDateTime.now() + ".jpg");
<小时/>

如果您不介意每次显示页面时都会重新下载图像,则可以使用 URL 中的变量参数使浏览器缓存失效。

model.addAttribute("image", "output.jpg?i=" + LocalDateTime.now());
<小时/>

将缓存控制与ETag结合使用,这涉及到您的图像不是静态的,应该由 Controller 管理。这是一个字节缓冲区的示例:

private static final CacheControl CACHE_CONTROL = CacheControl.noCache().cachePrivate().mustRevalidate();

@GetMapping(value = "/image", produces = { MediaType.IMAGE_JPEG_VALUE })
public ResponseEntity<byte[]> getImage(WebRequest webRequest) {
    byte[] imageBytes = // Load or generate the image bytes here
    String eTagId     = // Generate a unique eTagId for each version of your image
    if (webRequest.checkNotModified(eTagId))
        return ResponseEntity.status(HttpStatus.NOT_MODIFIED).body(null);

    return ResponseEntity.ok().cacheControl(CACHE_CONTROL).eTag(eTagId).body(imageBytes);
}

关于java - 如何确保目录中的图像在更改后刷新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56086135/

相关文章:

java - 页面滚动时 View 寻呼机内的回收器 View 不刷新

java - IntelliJ 无法同步目标文件夹中的更改

java - jsp问题request.getparameter

jquery - 如何在jquery selectize插件中设置从数据库中选择值

java - 如何在基于注释的配置文件中将另一个 bean 引用为属性

spring - 为什么用/manager/text 部署 tomcat7-maven-plugin 弄乱了上下文

java - 无状态 session Bean 与单例 session Bean

html - 如何将页面上的每个元素都变成滚动选取框?

html - 响应式图片库

java - 尝试使用 POST RestTemplate 调用外部 API 时出现 BadRequest 400