ThymeleafでReverse Proxyを使った際にURLを書き換える

tamuraです。

ローカルで開発しているときは問題なかったのに、 本番環境は reverse proxy を使っているので、 Thymeleafが生成するURLが違ってしまう場合がある、ということがあります。

/xxxx/app に来たアクセスを Tomcat の /app に横流しする

<Location /xxxx/app/>
  ProxyPass ajp://localhost:8009/app/
  ProxyPassReverse ajp://localhost:8009/app/
  ProxyPassReverseCookiePath /app/ /xxxx/app/
</Location>

このとき、このようなHTMLがあった場合

HTMlに書かれた内容

<a th:href="@{/next.html}">次へ</a>

通常であればこのようなHTMLが生成されます。

<a href="/app/next.html">次へ</a>

でも実際に生成してほしいHTMLはこのような形になります。

<a href="/xxxx/app/next.html">次へ</a>

Spring Bean で対応する

Spring Beanで proxy 用のパスを View 側から取得できるようにしておきます。

@ComponentScan
@Configuration
@EnableAutoConfiguration
public class Application {

    @Bean(name = "property")
    public AppProperties getProperties() {
        AppProperties app = new AppProperties();
        app.init("app.properties");
        return app;
    }

    @Bean(name = "proxy")
    @DependsOn("property")
    public ReverseProxyService getReverseProxyService() {
        return () -> getProperties().getReverseProxyPath();
    }

    public interface ReverseProxyService {
        public String getReverseProxy();
    }
}

プロパティファイルに定義した ProxyPath を取得できるようにしてあります。 Propertiesを直接参照するやり方でも大丈夫です。

Thymeleaf で書き換える

Thymeleaf で Sprign Bean の値を取得しつつ、URLを書き換えます。

Thymeleafは2.1です。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      th:with="proxyUrl=${@proxy.getReverseProxy()}">
<body>
  <a th:with="url=@{/next.html}" th:href="${#string.concat(proxyUrl, url)}">次へ</a>
</body>
</html>

これでHTMLを生成するとこのようになります。

<!DOCTYPE html>
<html>
<body>
  <a href="/xxxx/app/next.html">次へ</a>
</body>
</html>

関連記事

comments powered by Disqus