これを引き起こすルート コードは、Spring MVC にあり、WebContentGenerator から呼び出されます。このクラスは、MVC/Webflow スタックのいくつかのクラスの基本クラスとして使用されます。 + JSF HandlerAdapter)
0 の CacheControl 秒設定は、preventCaching メソッドを呼び出します。そのため、アプリケーションはデフォルトで 0 の設定になっているようです。
org.springframework.web.servlet.support.WebContentGenerator
protected final void preventCaching(HttpServletResponse response) {
response.setHeader(HEADER_PRAGMA, "no-cache");
if (this.useExpiresHeader) {
// HTTP 1.0 header
response.setDateHeader(HEADER_EXPIRES, 1L);
}
if (this.useCacheControlHeader) {
// HTTP 1.1 header: "no-cache" is the standard value,
// "no-store" is necessary to prevent caching on FireFox.
response.setHeader(HEADER_CACHE_CONTROL, "no-cache");
if (this.useCacheControlNoStore) {
response.addHeader(HEADER_CACHE_CONTROL, "no-store");
}
}
}
JSF + Webflow を使用しているため、JsfFlowHandlerAdapter が最初にフロー/ビューのサーバー要求を処理していることがわかりました。これが、JsfFlowHandlerAdapter がこの時点で Cache-Control およびその他の HTTP ヘッダーを既に設定しているため、インターセプターの構成が役に立たない理由です。FlowExecutionRestorationFailureException を処理するために JsfFlowHandlerAdapter を既に拡張していたことが判明したため (Sping Web Flow Preventing Back Button Use を参照)、必要な構成をWebContentInterceptorとして設定するだけで済みました (構成は基本クラス WebContentGenerator に属しているため)。
カスタム JsfFlowHandlerAdapter
public class MyAppFlowHandlerAdapter extends org.springframework.faces.webflow.JsfFlowHandlerAdapter {
...
}
webmvc-config.xml
<!-- Dispatches requests mapped to flows to FlowHandler implementations -->
<bean
class="com.myapp.MyAppFlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
<!-- Disable built in Cache-Control settings -->
<property name="cacheSeconds" value="-1" />
<property name="useExpiresHeader" value="false" />
<property name="useCacheControlHeader" value="false" />
<property name="useCacheControlNoStore" value="false" />
</bean>
<!-- Maps request paths to flows in the flowRegistry; e.g. a path of /hotels/booking
looks for a flow with id "hotels/booking" -->
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<!-- snip out unimportant -->
<property name="interceptors">
<list>
<ref bean="cacheControlInterceptor" />
</list>
</property>
</bean>
<bean id="cacheControlInterceptor"
class="com.myapp.CacheControlInterceptor">
CacheControlInterceptor (独自の HTTP ヘッダーを設定します。WebContentGenerator でそれを行うメソッドは final であるため、@Override はできません)
public class CacheControlInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//Example below: set your Cache-Control, expires, pragma headers here
response.setHeader("Cache-Control", "private");
return true;
}
}