11

クエリされた値を JSON として返すこのメソッドでスプリング キャッシュを使用します。

@RequestMapping("/getById")
@ResponseBody
@Cacheable
public HugeValue getHugeValueFromSlowFoo( @RequestParam(value = "id", defaultValue = "") String id ) {
  return Foo.getById( id );
}

これは正常に機能し、HugeValue オブジェクトがキャッシュ (この場合は Hazelcast) に格納されます。HugeValue から JSON を作成するのに時間がかかるため、これをさらに改善したいと考えています。オブジェクトの JSON 化されたバージョンをキャッシュするようにスプリング キャッシュに指示できますか?

Spring Boot 1.2およびSpring 4.1でJacksonを使用しています

4

3 に答える 3

9

あなたの正確なユースケースを本当に知らなくても(残念ながら、質問のためにコメントを追加することはまだ許可されていません)、私が考えているアイデアについて簡単に要約しようとします. それらはすべて、json マッピングに Jackson を使用し、少なくともSpring 3.1を使用することを前提としています。

私の知る限り、SpringMVC には enableResponseBodyCaching 機能はありません。

最初の選択肢: http 応答全体を本当にキャッシュしたいように見えるので、http キャッシュを使用します。Spring は、グローバル構成の簡単な方法を提供します。

<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"/>
    </bean>
</mvc:interceptors>

これを Controller ごとに制御したい場合は、Spring AbstractControllerを継承し、javaDoc に従って cacheSeconds プロパティを設定します。

もちろん、http キャッシングの真の力は、サーバーの前にある http プロキシに備わっています。

2 番目のアイデア: MappingJackson2HttpMessageConverterの独自のサブクラスを実装します。入力オブジェクトをマッピングする代わりにwriteInternal()、キャッシュにアクセスして既にマッピングされているバージョンを取得するロジックを追加できます。このアプローチは、Json ストリームの背後にある Java オブジェクトを取得するためにサービスをヒットすることを意味します。ある時点でキャッシュもあるためにこれで問題ない場合は、このアプローチを試してみる価値があります。

3 番目のアイデア:生の json 文字列/ストリームを提供する専用のラッパー サービスで、独自に json マッピングを行います。Jackson マッパー (クラス名ObjectMapper ) を簡単に挿入して、マッピングを完全に制御できます。このサービスに注釈を付けると、結果をキャッシュできます。コントローラーでは、使用したいタイプ (文字列またはストリーム)のResponseEntityのみを提供します。これにより、キャッシュされた結果が存在する場合、より深いサービス アクセスが妨げられることさえあります。

編集: おそらくMappingJackson2JsonViewも便利になる可能性があります。正直なところ、私はそれを使ったことがないので、その使用法については何も言えません.

インスピレーションを与えたり、助けたりすることを願っています! 乾杯

于 2015-01-13T08:05:30.847 に答える
1

Cache the json and put it in the response manually.

public void getHugeValueFromSlowFoo( @RequestParam(value = "id", defaultValue = "") String id, ServletResponse resp ) 
{
  String jsonSerializedHugeValue = Bar.getById(id); // serialize manually with ObjectMapper
  resp.getWriter().write(jsonSerializedHugeValue);
  resp.setContentType("application/json");
  resp.flushBuffer();
}
于 2016-06-09T06:53:59.877 に答える