0

Spring MVC でカスタム応答データ型を処理する必要があるときはいつでも、やや厄介に思えます。

私の場合、JavaScript コンテンツを返す必要があります。ただし、キャッシュにしたいです。

明確にするために、これは静的ファイルのケース ( <mvc:resources...) ではなく、サーバー上で生成された動的ファイルであり、キャッシュしたい (つまり、HttpResponse 200 と HttpResponse 302)。

コードに関しては、クライアント側では次のようにしています。

<script src="<spring:url value='/some-file.js'/>"></script>

SpringMVC コントローラーより:

@RequestMapping(value = "/some-file.js")
public ResponseEntity<String> resourceBundles(HttpServletRequest request, HttpServletResponse response, Locale locale) throws IOException {

    responseHeaders.add("Cache-Control", "public, max-age");
    responseHeaders.add("Content-Type", "text/javascript; charset=UTF-8");
    responseHeaders.add("Expires", "max-age");

    // Turn this into JSON response:
    String someJson = "{ a:a, b;b};";
    return new ResponseEntity<String>("var data = " + someJson, responseHeaders,  HttpStatus.OK);
}

ただし、ブラウザは常にこの動的 JS ファイルにアクセスしようとしているようです。

このファイルはセッションに依存するため、生成できず、静的ファイルとして扱います。

助言がありますか?

4

1 に答える 1

1

これは正しい動作です。ほとんどのブラウザは、ファイルが変更されたかどうかを確認するために、+ タイム スタンプを付けたGETリクエストを送信します。If-Modified-Since

通常、タイム スタンプを使用して、ファイルが変更されたかどうかを判断します。しかし、あなたのケースでは決して変わらないので、 ( / OKの代わりに)応答本文なしで304/応答で返信できます。HttpStatus.NOT_MODIFIED200

これは、ファイルが変更されていないことをブラウザに伝えます。

これはうまくいくはずです:

@RequestMapping(value = "/some-file.js")
public ResponseEntity<String> resourceBundles(
    HttpServletRequest request, 
    HttpServletResponse response, Locale locale) throws IOException {

    Date lmod = session.getAttribute("lmod");
    if( null == lmod ) {
        lmod = new Date();
        session.setAttribute("lmod", lmod);
    }

    responseHeaders.add("Last-Modified", lmod);

    String ifModifiedSince = request.getHeader("If-Modified-Since");
    if( null != ifModifiedSince ) { // You may want to compare lmod and ifModifiedSince here, too
        return new ResponseEntity( responseHeaders, HttpStatus.NOT_MODIFIED );
    }

    ... create first time response ...
}

ブラウザLast-Modifiedに通知すると、送信できるようになりますIf-Modified-Since

于 2012-07-25T09:54:25.907 に答える