2014-11-24 39 views
1

在Spring MVC應用程序,我們必須將調用JSP之前執行的控制器。 Controller將從數據庫中預取一些值並將它們設置在模型中並將控制權轉交給JSP。前CQ5在執行JSP如何調用一個Servlet /過濾器?

如何實現CQ 5這個功能嗎?我希望在執行JSP之前執行SlingFilter。 JSP不是一個頁面組件,而是一個出現在旁邊的組件。

注:

我可以寫我自己的SlingSerlvet,將預取我所需的值,使用的RequestDispatcher轉發到JSP做到這一點。 但用這種方法我將不得不通過像「/bin/.*」的URL。 而這又是在網頁級我想這種功能在組件級。

+1

如果你喜歡春天,你應該檢查這個。 http://neba.io/neba -in-a-nutshell.html – nerd 2014-11-24 14:47:02

+0

@nerd:令人驚歎的鏈接!你認爲這可以幫助我解決我的問題嗎?我正在瀏覽網站,但是您可以通過告訴我是否可以使用NEBA – Oliver 2014-11-25 05:30:16

回答

1

因此,要回答您的具體問題,如果您希望在調用組件之前執行過濾器,您將創建一個正在監聽組件級過濾器作用域的過濾器。

http://sling.apache.org/documentation/the-sling-engine/filters.html

那麼你將不得不您的過濾器更改來電請求到SlingServletRequest並確定目標資源就是你正在尋找的人。

但是,此篩選器將在頁面上包含的每個單個組件上執行。這可能對您有用的逆向過程是ResourceDecorator。

http://sling.apache.org/documentation/the-sling-engine/wrap-or-decorate-resources.html

這些當資源被確定執行,之前的servlet和過濾來電,這將讓你驗證,如果資源是一類你有興趣,然後允許你添加對資源對象的附加信息。然而,這又是一項將應用於所識別的每個資源的服務。

但是,如果你正在尋找的是隻針對特定路徑執行的過濾器,則沒有。吊索不這樣做。您提到Spring MVC和Spring MVC的MVC完全不同,然後是MVC的Slings版本。

編輯

因此,在傳統的web應用程序中,servlet將是在一個固定的位置,所有過濾器之前調用這個servlet應用。在Sling中,您將動態連接servlet以生成結果頁面。因此,每當您在servlet中並直接或間接調用請求調度程序時,它將再次執行解析過程,並在執行新servlet之前再次應用一系列過濾器

爲了防止需要僅應用於每個單一內部調度的主要請求的高級過濾器,他們提出了上下文或應用於不同時間並與不同時間關聯的過濾器鏈的想法包括的類型。

這是一個基本的過濾器,它會在被調用時記錄消息。我從記憶中做到了這一點,所以你需要用它來記住它。

@SlingFilter(scope = SlingFilterScope.COMPONENT, order = Integer.MIN_VALUE) 
public class SampleFilter implements Filter { 

    private static final Logger LOG = LoggerFactory.getLogger(SampleFilter.class); 

@Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request; 
     Resource res = slingRequest.getResource(); 
     if (!(res == null || ResourceUtil.isNonExistingResource(res))) { 
      LOG.error("this servlet is called before resource {} at path {}", res.getName(),res.getPath()); 
     } 
     chain.doFilter(request, response); 
    } 

} 

這樣做的重要組成部分,是範圍= SlingFilterScope.COMPONENT看看我在前面已經列出的網頁,並嘗試slignfilterscope的不同組合,你會看到它是如何被在不同的時間使用。 scope = SlingFilterScope.REQUEST將在每個頁面的基礎上位於頂層。

+0

您可以告訴我一個如何在組件呈現前調用過濾器的例子嗎?這會讓事情變得更容易 – Oliver 2014-11-25 14:04:56

+0

我在我的評論中添加了一些示例代碼 – 2014-11-25 19:47:28

+0

此過濾器在CQ5中的每個資源之前都被調用。在將數據添加到請求對象之前,我正在檢查一個條件'res.getResourceType()。equals(「myapp/components/mycomp」)',所以我不會最終爲錯誤的資源類型執行不必要的代碼。 **它工作,但我只是希望這是做到這一點的正確方法。** – Oliver 2014-11-26 09:43:56

0

但通過這種方法,我將不得不通過像「/bin/.*」這樣的URL。

您還可以針對資源類型以及路徑(例如,路徑)註冊servlet。 (from the Sling documentation):

@SlingServlet(
    resourceTypes = "sling/servlet/default", 
    selectors = "hello", 
    extensions = "html", 
    methods = "GET") 
public class MyServlet extends SlingSafeMethodsServlet { 

    @Override 
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException { 
     ... 
    } 
} 

如果刪除了「選擇」,「擴展」和註釋「辦法」的參數,這個servlet將結合對所有調用sling/servlet/default,而不需要對一組路徑結合。

+0

來節省我的努力是否有任何方法可以在CQ5中使用特定路徑/ URI作爲過濾器定義來過濾請求,使用選擇器?這是有用的說...如果我們想要修改行爲或包裝來自標準CQ5 extjs小部件的POST請求,我們不能指定選擇器? – vreddy 2014-11-24 19:56:42

1

就過濾器而言,JE Bailey的回答是正確的,但我懷疑你的問題可能以更適合Sling的世界觀的不同方式解決。

Sling提倡將OSGi服務用於業務邏輯,腳本應該是一個薄薄的層級。推薦您將邏輯移至OSGi服務並從腳本中調用這些服務。

您也可以看看Sling Models可以包括處理步驟(與@PostConstruct)渲染腳本踢前

相關問題