2016-02-10 40 views
1

在當前版本的grails(3.1.1,2016年2月)中,在控制器內部使用forward()會導致堆棧溢出。請注意,使用redirect()工作正常,但我有一個要求,該URL不能更改。爲什麼這個StackOverflow正在生成?Grails forward()導致StackOverflow錯誤

我確切的要求是檢查request.forwardURI對數據庫中的列表,如果它匹配發送數據返回該對象(如JSON,XML,HTML),而無需更改用戶的瀏覽器URL。所以我試圖解決這個問題是使用自定義的404錯誤處理程序,它檢查requestURI是否匹配任何內容,並在這種情況下發出forward()。 (注意:我也嘗試在matchAll()攔截器中做同樣的事情,但結果相同)。如果我使用redirect()而不是forward(),但是它改變了瀏覽器的URL,這對我來說是一個禁忌 - 我必須保留原始的瀏覽器URL。

我有a sample application you can run in github來重新創建這個bug,但是相關的部分在這裏給出。

內UrlMappings.groovy,我們發送404請求到自定義錯誤處理程序:

... 
"404"(controller: 'error', action:'notFound') 
... 

接下來,在ErrorController.groovy:NOTFOUND(),我們有問題,如果正向一些自定義邏輯必要的[不完全是我的要求,但接近]:

def notFound() { 
    if(request.forwardURI.contains("foo")){ // This special case should be forwarded to the foo controller. 
     log.warn("User requested Foo, sending to FooController..."); 
     forward(controller: 'foo', action: 'index'); 
     return; 
    } 
    // Now we can say it is not found for sure, and show error 
} 

我目前的解決辦法是實際發放從我的控制器到另一個控制器內的REST調用和返回的數據(避免任何重定向或轉發呼叫),這每次想到它都會讓人畏懼。

+0

如果你使用'redirect()',它能找到那個頁面嗎? StackOverflow很可能是因爲它處於無限循環/遞歸中而導致的。它無休止地試圖找到一個控制器,仍然得到一個404,採用相同的方法,等等。 (這就是爲什麼我添加了前一行,所以也許它沒有看到它作爲404) – Ivar

+0

@Ivar它可以找到沒有問題的頁面使用redirect(),一切都像你所期望的那樣工作。唯一的缺點是它違反了我的要求,URL不會改變。 –

+1

如果有人在乎這裏是我在grails-core上打開的錯誤:https://github.com/grails/grails-core/issues/9665 –

回答

0

看起來像這是某種錯誤,上面的代碼應該工作。

格雷姆已將其作爲阻擋者添加到3.0.15。

+0

如果有人在意,根據我的測試它在3.1.2中解決。 –