SpringBoot 中使用 Thymeleaf 展示图片

3,448 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情

1. Thymeleaf 回顾

对于 Thymeleaf 模板引擎的基础知识和在 SpringBoot 中的使用,在之前已经有所介绍,可以浏览一下,加深印象。

  1. Thymealeaf 基础

  2. SpringBoot 中引入 Thymeleaf

今天本篇文章来学习一下使用 Thymeleaf 模板引擎展示图片数据的方法。

2. HTML 页面图片展示

HTML 中展示图片的方式多种多样,其中最常用的有 页面背景图展示和 img 图片展示。

2.1 背景图片展示

对于 HTML 页面背景图片,需要对 html 中的 body 标签设置

  1. 通过 html 设置元素 (body) 标签的 background 属性
<body background="URL">
  1. 通过 css 设置元素 (body) 标签的 background-image 属性

  2. 使用 background-image 属性设置元素背景图片

<body style="background-image:url('URL')">
  • 默认从左上角开始,如果尺寸不足以填充,会在水平和垂直方向重复放置图片

  • 元素块背景的大小包括填充内容和边界,不包括边距

  • 其中的 URL 代表图片的地址,可以使用本地图片路径、网络图片路径、base64 编码、二进制流等形式展示图片

  • 图片是否重复放置可以通过背景图片的属性设置

<!-- background-repeat:no-repeat; 即不重复 -->
<!-- background-size:cover; 表示会将图片拉伸至填充大小 -->
<!-- background-position:center; 图片位置居中 -->
<body th:style="'background-image:url(' + @{/api/getRandomImage} + '); background-repeat:no-repeat;  background-size:cover;'">

背景相关属性

  • background 代表一整系列属性的简写,可以只传入图片路径,其他使用默认值
  • background-image 属性为元素设置背景图像
  • background-repeat 属性设置是否及如何重复背景图像。默认的背景图像在水平和垂直方向上重复。
  • background-size 属性规定背景图像的尺寸,可以设置 background-size: 100% 100%; 代表图片拉伸填充;100% 时与 background-size:cover; 一致

2.2 Thymeleaf 模板中设置背景图片

使用 Thymeleaf 的语法来动态展示后端传入的图片时,需要使用字符串拼接相关语法。

<!-- @{/api/getRandomImage} 代表 thymeleaf 请求后端的接口是 /api/getRandomImage 服务 -->
<body th:style="'background-image:url(' + @{/api/getRandomImage} + ');'">
    <!-- div 元素快背景设置 -->
    <div th:style="'background:url(' + @{/api/getRandomImage} + ');'"></div>
</body>
  • Thymeleaf 语法中需要通过操作 style 设置标签的背景属性值

  • 使用 Thymeleaf 语法时需要拼接,注意所有属性增加单字符来拼接字符串

  • html 中可能会无法识别 @ 符号,但是不影响使用

  • Thymeleaf 请求服务返回二进制流好使;返回 base64 图片显示不成功;

2.3 IMG 标签展示图片

img 标签展示图片是通过其属性 src 来指定图片源信息,src 内容同样有多种来源方式。

  1. 本地图片路径

  2. 网络图片路径

  3. base64 图片编码,需要在图片编码字符串增加前缀 data:image/png;base64,

  4. 图片二进制文件流

2.4 Thymeleaf 模板中设置 IMG 标签图片

使用 Thymeleaf 动态展示图片时,需要对 img 标签的 src 使用 th:src 替代,并在内容中设置后端接口路径,加载时动态请求服务将返回内容赋值到 img 元素中。

<!-- 如果不指定大小,则会根据图片实际大小将容器撑开 -->
<img style="height: 100%; width: 100%" th:src="@{/api/getRandomImage}">

3. 后端 Controller 返回图片二进制文件流

后端返回文件流时,可以通过响应体的方式返回或者通过二进制数组的方式返回。

3.1 HttpServletResponse 响应

返回类型为 void,使用请求参数中的 HttpServletResponse 来将流写入响应。

@GetMapping("/getRandomImage")
public void getRandomImage(HttpServletRequest request,HttpServletResponse response){
    response.setContentType("image/png");
    File file = new File("/img/path");
    InputStream in;
    try {
        in = new FileInputStream(file);
        OutputStream os = response.getOutputStream(); 
        byte[] b = new byte[1024];
        while (in.read(b) != -1) {
            os.write(b);
        }
        in.close();
        os.flush();
        os.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

3.2 ResponseEntity<byte[]> 数据返回

除了通过 HttpServletResponse 外,还可以将方法返回类型设置为 ResponseEntity<byte[]> ,将图片以二进制形式返回。

 @RequestMapping(value = "/api/getImage", produces = MediaType.IMAGE_PNG_VALUE)
public ResponseEntity<byte[]> getImage() throws Exception{
    // 获取本地文件的二进制流
    byte[] imageBytes ; = fileToByte(new File("/img/path"));
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.IMAGE_PNG);
    return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);
}