2017-02-22 1 views
1

RSSフィードを提供するためにspringを使用してRESTベースのWebサービスを開発しています。 RSSの更新は非常にまれで(週に2〜3回)、RSSフィードを誰かがリクエストするたびに作成するのではなく、キャッシュする必要があります。ここに私のコードです。私のWebサーバーを起動した後の私の最初のリクエストは、SubscriptionEventHandlerクラスのgetRssFeed()メソッドをヒットし、SubscriptionRssFeedViewに入り、buildFeedMetadata、buildFeedItemsメソッドなどを呼び出します。しかし、私は2番目のリクエストをするとSubscriptionEventHandlerのgetRssFeed()メソッドをスキップしますが、buildFeedMetadataではなくSubscriptionRssFeedViewのbuildFeedItemsメソッドが呼び出され、getIncidents()が呼び出され、RSSがゼロから再構築されます。私はここで Spring RESTキャッシングRSS AbstractRssFeedView

@CacheEvict

を呼び出すまで、私はこの問題を回避し、RSSをキャッシュすることができますが方法が私の SubscriptionRssFeedView

@Component("subscriptionRssView") 
public class SubscriptionRssFeedView extends AbstractRssFeedView 
{ 

    private String base_Url=”http://mycompany.com/”; 

    private final String feed_title = "My RSS Title "; 
    private final String feed_desc = "RSS feed desc"; 
    private final String feed_type = "rss_2.0"; 

    @Override 
    protected void buildFeedMetadata(Map<String, Object> model, Channel feed, HttpServletRequest request) 
    { 

     feed.setTitle(feed_title); 
     feed.setDescription(feed_desc); 
     feed.setLink(base_Url); 
     feed.setFeedType(feed_type); 

     super.buildFeedMetadata(model, feed, request); 
    } 


    @Override 
    protected List<Item> buildFeedItems(Map<String, Object> model, HttpServletRequest request, 
             HttpServletResponse response) throws Exception 
    { 
     List<Message> messageList = new ArrayList(Arrays.asList(getIncidents())); 

     List<Item> itemList = new ArrayList<Item>(messageList.size()); 

     for (Message message : messageList) 
     { 
      itemList.add(createItem(message)); 
     } 

     return itemList; 
    } 


    private Message[] getIncidents() 
    { 
     RestTemplate restTemplate = new RestTemplate(); 
     Message[] message = restTemplate.getForObject("http://xxxxx.com/api/message", Message[].class); 

     return message; 
    } 


    private Item createItem(Message message) 
    { 
     Item item = new Item(); 
     item.setLink(getFeedItemURL(message)); 
     item.setTitle(prepareFeedItemTitle(message)); 
     item.setDescription(createDescription(message)); 
     item.setPubDate(getLocalizedDateTimeasDate(message.getT())); 
     return item; 
    } 
} 

マイSubscriptionEventHandler

@Component("SubscriptionService") 
public class SubscriptionEventHandler implements SubscriptionService 
{ 

@Autowired 
private SubscriptionRssFeedView subscriptionRssFeedView; 


@Override 
@Cacheable("rssFeedCache") 
public SubscriptionRssFeedView getRssFeed() 
{ 
    return subscriptionRssFeedView; 
} 

} 

マイSubscriptionServiceです

@Service 
public interface SubscriptionService 
{ 
    SubscriptionRssFeedView getRssFeed(); 
} 

マイSubscriptionControllerは

@Controller 
@RequestMapping("/subscription") 
public class SubscriptionController 
{ 

@Autowired 
private SubscriptionService subscriptionService; 


@RequestMapping(value = "/rss", method = RequestMethod.GET) 
public SubscriptionRssFeedView getRSS() throws Exception 
{ 
    return subscriptionService.getRssFeed(); 
} 
} 
+0

私の更新されたコメントを確認してください – artemisian

答えて

0

あなたSubscriptionControllerあなたSubscriptionRssFeedViewのrender方法のレスポンスのレンダリング常に呼び出されます。このメソッドは、buildFeedMetadata、buildFeedEntriesなどの呼び出しをトリガーするメソッドです。シーケンスは以下の通りである。

AbstractView.render => AbstractFeedView.renderMergedOutputModel => SubscriptionRssFeedView.buildFeedMetadataとSubscriptionRssFeedView.buildFeedEntries

あなたは親クラスのメソッドAbstractView.renderとAbstractFeedView.renderMergedOutputModelを確認することができますそれらのメソッドへの呼び出しをトリガする詳細を参照したい場合は、。あなたに

は、あなたがそうでなければgetIncidentsに対するすべての呼び出しは、常に同じ値を返します代わりに、私はあなたのキャッシュへのキーを追加することをお勧めSubscriptionEventHandler.getRssFeed()

SubscriptionRssFeedView.getIncidents()方法をキャッシュすることができますRSSを再計算しないようにすると、これは望ましくないだろう複数のフィードがある場合

+0

私は、デバッグ時に初めてgetRssFeed()メソッドが呼び出され、その後のすべての呼び出しでこのメソッドが実行されないので、そのケースは考えません。だから私はそれがキャッシュからsubscriptionRssFeedViewオブジェクトを選んでいると確信しています。しかし、以前に生成された出力を提供するのではなく、すべてを再構築します。 – user864309

+0

申し訳ありませんが、私は非argメソッドのデフォルトのキー戦略について間違っていました。私は私の答えを更新しました。 – artemisian

関連する問題