読者です 読者をやめる 読者になる 読者になる

Spring MVC でのレスポンスのキャッシュ制御 #spadc13

Spring Framework Advent Calendar 2013 - Adventar 9日目です。

ということで、
Spring Framework Advent Calendar 2013 - Adventarに参加することとなりました。

Spring MVC 3.2 にて、レスポンスのキャッシュを制御する機能を調べましたので整理します。
URLのパスパターンでキャッシュの有効期限が個別に設定できたり便利です。
デフォルトですとキャッシュ関連のヘッダーは何も出力しません。

以下、 servlet-context.xml の設定例です。WebContentInterceptorクラスを登録します。

<mvc:interceptors>
  <bean id="webContentInterceptor"
        class="org.springframework.web.servlet.mvc.WebContentInterceptor">
    <property name="cacheSeconds" value="0"/>
    <property name="useExpiresHeader" value="true"/>
    <property name="useCacheControlHeader" value="true"/>
    <property name="useCacheControlNoStore" value="true"/>
    <property name="cacheMappings">
      <props>
        <prop key="/assets/**">2592000</prop>
      </props>
    </property>
  </bean>
</mvc:interceptors>

各プロパティーの説明は、以下です。

cacheSeconds

キャッシュの有効期限を指定します。

  • -1(デフォルト): キャッシュ関連のヘッダーを出力しません。
  • 0: no cache 関連のヘッダーが出力されます。
  • 1以上: 例えば10を指定した場合、'Cache-Control: max-age=10'のようなヘッダが出力されます。

useExpiresHeader

trueの場合、以下のヘッダが出力されます。

Expires: Thu, 01 Jan 1970 00:00:00 GMT

デフォルトは、trueです。

useCacheControlHeader

trueの場合、以下のヘッダが出力されます。

Cache-Control: no-cache

デフォルトは、trueです。

useCacheControlNoStore

trueの場合、以下のヘッダが出力されます。

Cache-Control: no-store

デフォルトは、trueです。

cacheMappings

動的リソースを返す場合は、上記のグローバルな設定でno cacheで良いと思うんですが、静的リソースを返すパスはキャッシュを有効にしたくなると思います。
その場合、このプロパティーでURLのパス単位で、キャッシュの有効時間(秒)を指定できます。

URLのパス指定は、Antのパスパターンで指定が可能で、'/assets/**' と指定すれば、 assets 配下のすべてのパスに適用されます。

以上です。

色んな Java Web フレームワークを模索してきましたが、Spring MVCは調べれば痒いところに手が届くようになっていて良いフレームワークだなと思いました。

余談

6日目のエントリ を読んで、そんな方法があったんだーと喜びました。
自分は、どうやってたのかというと、OValのアノテーション使って、when属性でSPEL使って対象文字列が1文字以上だったらチェックという感じで非常に面倒な事をやってました。。
最近のフレームワークって自前でバリデーション機能持ってなくてBean Validationに任せる感じなので他のフレームワークでも同じ問題に突き当たりそうな気がする。