1. 概要

このチュートリアルでは、XMLとJavaの両方の構成を使用して、Springで静的リソースを提供する方法について説明します。

2. スプリングブートの使用

Spring Bootには、静的リソースの提供を容易にするために、ResourceHttpRequestHandlerの事前構成された実装が付属しています。

デフォルトでは、このハンドラーは、クラスパスにある/ static、/ public、/ resources、および/ META-INF/resourcesディレクトリのいずれかから静的コンテンツを提供します。 src / main / resources は通常、デフォルトでクラスパス上にあるため、これらのディレクトリのいずれかをそこに配置できます。

たとえば、クラスパスの /staticディレクトリ内にabout.htmlファイルを配置すると、 http:// localhost:8080/を介してそのファイルにアクセスできます。 about.html。 同様に、他の言及されたディレクトリにそのファイルを追加することによって、同じ結果を達成することができます。

2.1. カスタムパスパターン

デフォルトでは、SpringBootはリクエストのルート部分の下にあるすべての静的コンテンツを提供します。 / ** 。 これは適切なデフォルト構成のように見えますが、 spring.mvc.static-path-patternを介して変更できます構成プロパティ。 

たとえば、 http:// localhost:8080 / content / about.htmlを介して同じファイルにアクセスする場合、 application.properties:でそのように言うことができます。

spring.mvc.static-path-pattern=/content/**

WebFlux環境では、spring.webflux.static-path-patternプロパティを使用する必要があります。

2.2. カスタムディレクトリ

パスパターンと同様に、 spring.web.resources.static-locations構成プロパティを使用してデフォルトのリソースの場所を変更することもできます。 このプロパティは、複数のコンマ区切りのリソースの場所を受け入れることができます。

spring.web.resources.static-locations=classpath:/files/,classpath:/static-files

ここでは、クラスパス内の /filesおよび/static-filesディレクトリから静的コンテンツを提供しています。 さらに、 Spring Bootは、クラスパスの外部から静的ファイルを提供できます。

spring.web.resources.static-locations=file:/opt/files

ここでは、ファイルリソース署名 file:/ を使用して、ローカルディスクからファイルを提供しています。

3. XML構成

XMLベースの構成で昔ながらの方法を採用する必要がある場合は、 mvc:resources 要素をうまく利用して、特定のパブリックURLパターンを持つリソースの場所を指すことができます。

たとえば、次の行は、「/ resources / 」を検索して、「 / resources / **」、などのパブリックURLパターンで着信するリソースに対するすべてのリクエストを処理します。アプリケーションのルートフォルダの下にあるディレクトリ:

<mvc:resources mapping="/resources/**" location="/resources/" />

これで、次のHTMLページのようにCSSファイルにアクセスできます。

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
    <link href="<c:url value="/resources/myCss.css" />" rel="stylesheet">
    <title>Home</title>
</head>
<body>
    <h1>Hello world!</h1>
</body>
</html>

4. ResourceHttpRequestHandler

春3.1。 を導入しました ResourceHand lerRegistry 構成するには ResourceHttpRequestHandler s クラスパス、WAR、またはファイルシステムから静的リソースを提供するため。 設定できます ResourceHandlerRegistry プログラムでWebコンテキスト構成クラス内にあります。

4.1. WARに保存されているリソースを提供する

これを説明するために、以前と同じURLを使用して myCss.css をポイントしますが、実際のファイルはWARの webapp /resourcesフォルダーにあります。 Spring 3.1以降のアプリケーションをデプロイするときに静的リソースを配置する場所:

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
          .addResourceHandler("/resources/**")
          .addResourceLocations("/resources/");	
    }
}

この例を少し分析してみましょう。 まず、リソースハンドラーを定義して、外部向けURIパスを構成します。 次に、その外部向けURIパスを、リソースが実際に配置されている物理パスに内部的にマップします。

もちろん、このシンプルでありながら柔軟なAPIを使用して、複数のリソースハンドラーを定義できます。

これで、 html ページの次の行で、 webapp /resourcesディレクトリ内のmyCss.cssリソースが取得されます。

<link href="<c:url value="/resources/myCss.css" />" rel="stylesheet">

4.2. ファイルシステムに保存されているリソースを提供する

/ files / ** パターンに一致するパブリックURLのリクエストが届くたびに、 / opt / files/ディレクトリに保存されているリソースを提供するとします。 URLパターンを構成し、それをディスク上の特定の場所にマップするだけです。

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry
      .addResourceHandler("/files/**")
      .addResourceLocations("file:/opt/files/");
 }

Windowsユーザーの場合、この例で addResourceLocations に渡される引数は、「 file:/// C:/ opt / files/」になります。

リソースの場所を設定したら、 home.html のマップされたURLパターンを使用して、ファイルシステムに保存されている画像をロードできます:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
    <link href="<c:url value="/resources/myCss.css" />" rel="stylesheet">
    <title>Home</title>
</head>
<body>
    <h1>Hello world!</h1>
    <img alt="image"  src="<c:url value="files/myImage.png" />">
</body>
</html>

4.3. リソースの複数の場所の構成

複数の場所でリソースを探したい場合はどうなりますか?

addResourceLocations メソッドを使用して、複数の場所を含めることができます。 リソースが見つかるまで、場所のリストが順番に検索されます。

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry
      .addResourceHandler("/resources/**")
      .addResourceLocations("/resources/","classpath:/other-resources/");
}

次のcurlリクエストは、クラスパスのアプリケーションの webappp /resourcesまたはother-resourcesフォルダーに保存されているHello.htmlページを表示します。

curl -i http://localhost:8080/handling-spring-static-resources/resources/Hello.html

5. 新しいResourceResolvers

春4.1。 新しいResourcesResolvers、で、静的リソースをロードするときにブラウザーのパフォーマンスを最適化するために使用できるさまざまなタイプのリソースリゾルバーを提供します。 これらのリゾルバーは、リクエスト処理を最適化するために、ブラウザーにチェーンしてキャッシュすることができます。

5.1. PathResourceResolver

これは最も単純なリゾルバーであり、その目的は、パブリックURLパターンが指定されたリソースを見つけることです。 実際、ResourceResolverResourceChainRegistrationに追加しない場合、これがデフォルトのリゾルバーです。

例を見てみましょう:

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry
      .addResourceHandler("/resources/**")
      .addResourceLocations("/resources/","/other-resources/")
      .setCachePeriod(3600)
      .resourceChain(true)
      .addResolver(new PathResourceResolver());
}

注意事項:

  • リソースチェーンのPathResourceResolverを、その中の唯一のResourceResolverとして登録しています。 セクション4.3を参照できます。 複数のResourceResolverをチェーンする方法を確認します。
  • 提供されるリソースは、3600秒間ブラウザにキャッシュされます。
  • チェーンは最終的にメソッドresourceChain(true)で構成されます。

ここで、 PathResourceResolver と組み合わせて、 webapp /resourcesまたはwebapp/のいずれかにあるfoo.jsスクリプトを検索するHTMLコードについて説明します。 other-resources フォルダー:

<script type="text/javascript" src="<c:url value="/resources/foo.js" />">

5.2. EncodedResourceResolver

このリゾルバーは、Accept-Encodingリクエストヘッダー値に基づいてエンコードされたリソースを見つけようとします。

たとえば、 gzip コンテンツコーディングを使用して静的リソースの圧縮バージョンを提供することにより、帯域幅を最適化する必要がある場合があります。

EncodedResourceResolver、を構成するには、 PathResourceResolver を構成したのと同じように、 ResourceChain、で構成する必要があります。

registry
  .addResourceHandler("/other-files/**")
  .addResourceLocations("file:/Users/Me/")
  .setCachePeriod(3600)
  .resourceChain(true)
  .addResolver(new EncodedResourceResolver());

デフォルトでは、 EncodedResourceResolver は、brおよびgzipコーディングをサポートするように構成されています。

したがって、次の curl リクエストは、 Users / Me/ディレクトリのファイルシステムにあるHome.htmlファイルのzipバージョンを取得します。

curl -H  "Accept-Encoding:gzip" 
  http://localhost:8080/handling-spring-static-resources/other-files/Hello.html

どのように注意してくださいヘッダーの「Accept-Encoding」値をgzipに設定しています。 この特定のリゾルバーは、gzipコンテンツが応答に対して有効である場合にのみ起動するため、これは重要です。

最後に、以前と同じように、圧縮バージョンはブラウザにキャッシュされている間(この場合は3600秒)利用可能であることに注意してください。

5.3. チェーンResourceResolvers

リソースルックアップを最適化するために、ResourceResolversはリソースの処理を他のリゾルバーに委任できます。 チェーンに委任できない唯一のリゾルバーはPathResourceResolver、であり、チェーンの最後に追加する必要があります。

実際、resourceChaintrueに設定されていない場合、デフォルトではPathResourceResolverのみがリソースの提供に使用されます。 ここでは、 GzipResourceResolver が失敗した場合にリソースを解決するために、PathResourceResolverをチェーンしています。

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry
      .addResourceHandler("/js/**")
      .addResourceLocations("/js/")
      .setCachePeriod(3600)
      .resourceChain(true)
      .addResolver(new GzipResourceResolver())
      .addResolver(new PathResourceResolver());
}

/ js /**パターンをResourceHandlerに追加したので、webappにあるfoo.jsリソースを含めましょう。 home.htmlページの/js/ ディレクトリ:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
    <link href="<c:url value="/resources/bootstrap.css" />" rel="stylesheet" />
    <script type="text/javascript"  src="<c:url value="/js/foo.js" />"></script>
    <title>Home</title>
</head>
<body>
    <h1>This is Home!</h1>
    <img alt="bunny hop image"  src="<c:url value="files/myImage.png" />" />
    <input type = "button" value="Click to Test Js File" onclick = "testing();" />
</body>
</html>

Spring Framework 5.1の時点で、 GzipResourceResolver は非推奨になり、EncodedResourceResolverが採用されました。 したがって、将来的には使用しないようにする必要があります。

6. 追加のセキュリティ構成

Springセキュリティを使用する場合は、静的リソースへのアクセスを許可することが重要です。 リソースURLにアクセスするための対応する権限を追加する必要があります。

<intercept-url pattern="/files/**" access="permitAll" />
<intercept-url pattern="/other-files/**/" access="permitAll" />
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/js/**" access="permitAll" />

7. 結論

この記事では、Springアプリケーションが静的リソースを提供できるさまざまな方法を説明しました。

XMLベースのリソース構成はレガシーオプションであり、Java構成ルートをまだ下ることができない場合に使用できます。

春3.1。 で出てきたそのを介して基本的なプログラムの代替 ResourceHandlerRegistry 物体。

最後に、がSpring4.1に同梱された新しいResourceResolversおよびResourceChainRegistrationオブジェクト。 静的リソースの提供効率を向上させるために、キャッシングやリソースハンドラーチェーンなどのリソース読み込み最適化機能を提供します。

いつものように、完全な例はGithubから入手できます。 さらに、このプロジェクトではSpringBoot関連のソースコードも利用できます