有没有一种方法可以显示编码成超过100000个字符的字符串的图像?(Java,Spring,Thymeleaf)

mrphzbgm  于 2023-05-12  发布在  Java
关注(0)|答案(1)|浏览(182)

因此,我有一个表单,允许用户上传一个图像,它将被编码为IOUtils.toByteArray,并作为一个字节持久化到数据库。在一个控制器方法中,我得到这个字节数组并将其编码为字符串:

@GetMapping("/{user_id}")
public String view(@PathVariable("user_id") Long user_id, Model model) {
    User user = userService.getById(user_id);
    model.addAttribute("user", user);
    byte[] profilePictureBytes = user.getProfilePicture();

    if (profilePictureBytes != null) {
        String encodedImage = Base64.getEncoder().encodeToString(profilePictureBytes);
        model.addAttribute("encodedImage", encodedImage);
    }
    return "user-page";
}

在一个用户页面的html文件中,我尝试像这样解码它:

<img th:attr="src=${'data:image/jpeg;base64,' + encodedImage}" alt="Profile Picture">

此解决方案适用于较小的图像,但当编码图像超过100 000个字符时会引发异常:

org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "'data:image/jpeg;base64,' + encodedImage" (template: "user-page" - line 27, col 6)

org.springframework.expression.spel.SpelEvaluationException: EL1078E: Concatenated string is too long, exceeding the threshold of '100 000' characters

有没有办法绕过这个限制,或者我应该改变整个程序的逻辑?谢谢大家。

wqlqzqxt

wqlqzqxt1#

这一个是棘手的!TY,@Andrey(,再次;)用于准确地指出“问题”。我不确定,是否值得为此打开一个 Spring 问题/请求/增强。
但是:

  • (看起来,github搜索)此检查仅适用于(Spring EL)“字符串连接”
  • 来“规避”我们可以...使用Thymeleaf功能:
  • 无法使它与“内联表达式”一起工作,然而……(似乎不能与“attrs”一起工作)
  • 但是用th:attrappend!!;)(而不是Spring EL string concat;)

生成的模板:

<img src="data:image/jpeg;base64," th:attrappend="src=${encodedImage}" alt="Profile Picture">

(测试)使用的控制器:

@Controller
class DemoController {

    final String encodedImage;

    public DemoController(
            @Value("classpath:/bigImage.jpg") /* source: https://github.com/samdutton/simpl/blob/main/bigimage/bigImage.jpg */
            Resource bigPic) throws IOException {
        this.encodedImage = Base64.getEncoder().encodeToString(bigPic.getContentAsByteArray());
    }

    @ModelAttribute("encodedImage")
    public String encodedImage() throws IOException {
        return encodedImage;
    }

    @GetMapping("/test")
    public String test() {
        return "test";
    }
}

一般

这些类型的东西属于负载均衡器的缓存!(..而不是进入你的“后端”的“内存”(byte[], Base64...):)

高级

将这些(类似于)东西(附加到html/http响应)类似于https://www.thymeleaf.org/doc/articles/springmail.html,就像:

  • 模板:
<img src="sample.png" th:src="|cid:${imageResourceName}|" />
  • 但不幸的是,我们不能(我还没有找到它,如MimeMessageaddInline

另一种(简单)解决方法

@ModelAttribute("encodedImageAttr")
public String encodedImageAttr() throws IOException {
    return String.format("data:image/jpeg;base64,%s", encodedImage);;
}

...提供完整的属性值,而不是“base64部分”。
然后模板看起来像:

<img src="" th:attr="src=${encodedImageAttr}" alt="Profile Picture">

(我也尝试了模板SpEL th:attr="src=${#T(java.lang.String).format('data:image/jpeg;base64,%s', encodedImageAttr)}",但失败了,因为:

...
Caused by: org.attoparser.ParseException: Instantiation of new objects and access to static classes or parameters is forbidden in this context (template: "test" - line 6, col 17)
    at org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)
    at org.attoparser.MarkupParser.parse(MarkupParser.java:257)
    at org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:230)
    ... 52 more
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Instantiation of new objects and access to static classes or parameters is forbidden in this context (template: "test" - line 6, col 17)
    at org.thymeleaf.spring6.expression.SPELVariableExpressionEvaluator.obtainComputedSpelExpression(SPELVariableExpressionEvaluator.java:309)
    at org.thymeleaf.spring6.expression.SPELVariableExpressionEvaluator.evaluate(SPELVariableExpressionEvaluator.java:182)
    at org.thymeleaf.standard.expression.VariableExpression.executeVariableExpression(VariableExpression.java:166)
    at org.thymeleaf.standard.expression.SimpleExpression.executeSimple(SimpleExpression.java:66)
    at org.thymeleaf.standard.expression.Expression.execute(Expression.java:109)
...

相关问题