LoginSignup
9
4

More than 5 years have passed since last update.

Spring Boot + ThymeleafでSpringTemplateEngineをカスタマイズする

Last updated at Posted at 2017-06-17

やりたいこと

Thymeleafでリンクを生成する部分を拡張したい。

ThymeleafでURLを指定するときのこれ

<img th:src="@{/image/hoge.jpg}">

ホスト名がふくまれてないときに、CDNのホスト名をリンクに追加したい。

ex) /image/hoge.jpg -> http://cdn.example.com/image/hoge.jpgみたいにする


環境

  • SpringBoot: 1.4.6.RELEASE
  • Thymeleaf: 3.0.2.RELEASE

実装

org.thymeleaf.linkbuilder.AbstractLinkBuilderを拡張したクラスを作成します。

リンクを生成する部分をbuildLinkメソッドに実装します。

CDNのホストを追加する必要がない場合は、デフォルトのURLを利用したいのでStandardLinkBuilderを利用しています。

http://example.com/xxxのように始まるリンクは、CDNのホストを追加しないようにしています。

if (UrlUtils.isAbsoluteUrl(link)) { ... }のところ

@Component
public class CustomLinkBuilder extends AbstractLinkBuilder {
    private static final Logger LOGGER = LoggerFactory.getLogger(CustomLinkBuilder.class);
    private final StandardLinkBuilder standardLinkBuilder = new StandardLinkBuilder();

    private String cdnHost() {
        return "http://localhost:8080";
    }

    private boolean isImageExtention(String path) {
        return StringUtils.endsWith(path, ".jpg")
                || StringUtils.endsWith(path, ".jpeg")
                || StringUtils.endsWith(path, ".png")
                || StringUtils.endsWith(path, ".gif");
    }

    private boolean isImageLink(UriComponents components) {
        final String path = components.getPath();
        return StringUtils.startsWith(path, "/image/") && this.isImageExtention(path);
    }

    @Override
    public String buildLink(final IExpressionContext context, final String base, final Map<String, Object> parameters) {
        String link = this.standardLinkBuilder.buildLink(context, base, parameters);
        LOGGER.debug("build link:{}", link);

        if (UrlUtils.isAbsoluteUrl(link)) {
            return link;
        }

        UriComponents components = UriComponentsBuilder.fromUriString(link).build();

        if (this.isImageLink(components)) {
            return this.cdnHost() + link;
        }

        return link;
    }
}

TemplateEngineに、↑のクラスを設定します。

デフォルトのSpringTemplateEngineに、CustomLinkBuilderを設定したかったので、@Import(ThymeleafAutoConfiguration.class)しています。

@ImportがないとSpringTemplateEngineのBeanが生成されるタイミングより前に、@Bean SpringTemplateEngine customTemplateEngine() {}が実行されるため、
@Autowired private SpringTemplateEngine templateEngineがnullになるようです。

@Configuration
@Import(ThymeleafAutoConfiguration.class)
public class WebConfig {
    @Autowired
    private SpringTemplateEngine templateEngine;
    @Autowired
    private CustomLinkBuilder customLinkBuilder;

    @Bean
    public SpringTemplateEngine customTemplateEngine() {
        this.templateEngine.setLinkBuilder(this.customLinkBuilder);
        return this.templateEngine;
    }
}

これで、<img th:src="@{/image/hoge/main.jpg}">のようにtemplateに書くと、
<img src="http://localhost:8080/image/hoge/main.jpg">と表示されます。


今回のソースはこちらになります。
参考になれば幸いです:sweat_smile:

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4