在當前版本的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調用和返回的數據(避免任何重定向或轉發呼叫),這每次想到它都會讓人畏懼。
如果你使用'redirect()',它能找到那個頁面嗎? StackOverflow很可能是因爲它處於無限循環/遞歸中而導致的。它無休止地試圖找到一個控制器,仍然得到一個404,採用相同的方法,等等。 (這就是爲什麼我添加了前一行,所以也許它沒有看到它作爲404) – Ivar
@Ivar它可以找到沒有問題的頁面使用redirect(),一切都像你所期望的那樣工作。唯一的缺點是它違反了我的要求,URL不會改變。 –
如果有人在乎這裏是我在grails-core上打開的錯誤:https://github.com/grails/grails-core/issues/9665 –