提问者:小点点

在Thymeleaf生成的超文本标记语言文档中包含<img>


在我的Spring Boot应用程序中,我正在使用Thymeleaf生成超文本标记语言电子邮件。我想包含一个

我已经确认可以通过在本地启动应用程序并在浏览器中请求http://localhost:8080/img/logo.svg来解析图像。

为了将此图像包含在超文本标记语言中,我尝试了以下所有方法

其中每一项的结果是:

  1. 抛出异常:org. thymeleaf.异常。TemplateProcessingException:链接库“/img/logo.svg”不能是上下文相关的(/…),除非用于执行引擎的上下文实现了org.thymeleaf.context.IWebContext接口
  2. 渲染

我想为了在电子邮件中正确呈现图像,我需要提供一个绝对的URL,但我不确定如何实现。

问题的一部分是,不明显的是电子邮件没有显示是因为URL不正确,还是因为电子邮件客户端阻止了图像。

我认为这是显而易见的,但显然不是:我不能使用任何将主机名硬编码为localhost:8080的解决方案,因为这只是我在本地运行时使用的URL,我也需要它在其他环境中工作,例如prod


共2个答案

匿名用户

您引入了一个声明公共url的属性(例如在application.properties中):

public_domain=http://somwhere.com

像这样使用它:

<img th:src="@{|${public_domain}/img/logo.svg|}" />

喜欢这里。

<img th:scr="${#httpServletRequest.scheme}+'://'+${#httpServletRequest.serverName}+':'+${#httpServletRequest.serverPort}+@{img/logo.svg}" />

超级酷!!(这只适用于超文本传输协议(servlet)请求,这在这里似乎不相关。)

您永远不知道谁使用任何客户端“观看”您的电子邮件(,它信任任何服务器…并从中加载图像)!!?….

因此,在[so]中将图像嵌入html电子邮件是一个“非常流行”的问题。

并应用于thymeleaf:他们有一篇额外的文章!!(也显示img附件…在html和文本中工作(没有图像;()!!!;)

总结一下(,一旦配置了邮件和模板):

模板:

 <img src="sample.png" th:src="|cid:${imageResourceName}|" />

img元素有一个硬编码的src值-非常适合原型设计-,它将在运行时被与附加图像文件名匹配的cid: image.jpg之类的东西替换。

服务:

String imageResourceName = ...
byte[] imageBytes = ...
String imageContentType = ...

// Prepare the evaluation context
final Context ctx = new Context(locale);
...
ctx.setVariable("imageResourceName", imageResourceName); // so that we can reference it from HTML

// Prepare message using a Spring helper
final MimeMessage mimeMessage = this.mailSender.createMimeMessage();
final MimeMessageHelper message = ...
message.set...

// Create the HTML body using Thymeleaf
final String htmlContent = ...

// Add the inline image, referenced from the HTML code as "cid:${imageResourceName}" !!!
final InputStreamSource imageSource = new ByteArrayResource(imageBytes);
message.addInline(imageResourceName, imageSource, imageContentType);

// Send mail ...

匿名用户

所以“战略上”我们有两个选择:

  • A:提供图像(来自具有静态url的公共服务器)。
  • B:发送“带有电子邮件正文”的图像。

(优点,缺点,…)

我们应该按照Thymeleaf的建议,把它作为一个“绝对URL”来做:

绝对URL允许您创建到其他服务器的链接。它们首先指定协议名称(超文本传输协议://或https://)…

它们根本没有被修改(除非您在服务器上配置了URL重写过滤器并在HttpServletResponse. inkdeUrl(…)方法中执行修改)…

<img th:src="@{http://localhost:8080/img/logo.svg}" />

这将呈现给:

<img src="http://localhost:8080/img/logo.svg" />

(无论邮件客户端将如何处理它)

我们可以通过引入

(例如)application.properties:

public_domain=http://somewhere.com

像这样使用它:

<img th:src="@{|${public_domain}/img/logo.svg|}" />

喜欢这里。

在这里,我们有(技术上)的选项:

  • 内联附加(

配置模板和邮件后,Thymeleaf文章的大纲是:

模板html:

 <img src="/path/when/not/thymeleaf-generated/logo.svg" th:src="|cid:${imageResourceName}|" />

img元素有一个硬编码的src值-非常适合原型设计-,它将在运行时被与附加图像文件名匹配的cid: image.jpg之类的东西替换。

服务java:

String imageResourceName = ...
byte[] imageBytes = ...
String imageContentType = ... // availabe!

// Prepare the evaluation context
final Context ctx = new Context(locale);
...
ctx.setVariable("imageResourceName", imageResourceName); // so that we can reference it from HTML

// See Article...

// Add the inline image, referenced from the HTML code as "cid:${imageResourceName}" !!!
final InputStreamSource imageSource = new ByteArrayResource(imageBytes);
message.addInline(imageResourceName, imageSource, imageContentType);

// Send mail ...