三種思路實現自訂404頁面,思路自訂404頁面
如何定義404
404,說白了就是找不到頁面,那麼如何定義“找不到”呢?
我們可以通過原始碼來看看Spring MVC如何定義“404”的:
// Determine handler for the current request.mappedHandler = getHandler(processedRequest, false);if (mappedHandler == null || mappedHandler.getHandler() == null) {noHandlerFound(processedRequest, response);return;}
getHandler是根據請求的url,通過handlerMapping來匹配到Controller的過程。
如果匹配不到,那麼就執行noHandlerFound方法。這個方法很簡單,返回一個404的錯誤碼。
我們的Web容器,比如tomcat,會根據這個錯誤碼來產生一個錯誤介面給使用者。
那麼,我們如何自訂這個介面呢?
重寫noHandlerFound方法
最先想到的肯定是重寫noHandlerFound方法,這個方法是protected,可以重寫。
我們需要將頁面重新導向到我們自訂的404介面,那麼只需要
@Overrideprotected void noHandlerFound(HttpServletRequest request,HttpServletResponse response) throws Exception {response.sendRedirect(request.getContextPath() + "/notFound");}
這裡我們的Controller裡需要定義一個@requestMapping("/notFound")的這麼一個方法,用來返回一個404頁面
或者,這裡應該可以採用直接存取靜態檔案的方法。
另外,也可以通過拋出一個異常NoSuchRequestHandlingMethodException
這樣我們就實現了自訂的404頁面。那麼,還有別的方法嗎?
利用Spring MVC的最精確匹配
Spring MVC對於url的匹配採用的是一種叫做“最精確匹配的方式”,舉個例子
比如我們同時定義了“/test/a”, "/test/*",那麼若請求的url結尾為/test/a,那麼則會匹配精確的那個,也就是"/test/a"
我們是不是可以利用這個特點來找到那些找不到的頁面?
1、首先我們定義一個攔截所有url的規則@requestMapping("*"),那麼實際上不存在找不到的頁面了,也就是永遠不會進入noHandlerFound方法體內
2、後面的步驟和平時一樣,為別的請求都配置上@requestMapping
那麼請求過來,要麼進入我們精確匹配的method(也就是找的到的),要麼進入@requestMapping("*)攔截的方法體內(也就是找不到的)
那麼我們只要讓@requestMapping("*)攔截的這個方法返回一個自訂的404介面就OK了~
利用web容器提供的error-page
還記得之前提到的web容器會提供一個404的預設介面嗎?
其實我們完全可以替換成我們自己的介面,那麼看起來這種方法應該是最簡單的了。
只需要在web.xml檔案中寫上如下代碼就可以了:
<error-page><error-code>404</error-code><location>/resource/view/404.htm</location></error-page>
不過值得注意的是,這裡配置的的location其實會被當成一個請求來訪問。
那麼我們的DispatcherServlet會攔截這個請求而造成無法訪問,此時的結果是使用者介面一片空白。
所以這裡的404.htm其實是一個靜態資源,我們需要用訪問靜態資源的方式去訪問。
而在我的Spring MVC裡,resource目錄下的檔案都是不會被攔截的
比較三種方式的區別
1、最方便:那肯定是第三種了,我們只需要提供一個靜態頁面即可2、最快捷:第一種肯定最慢,因為它會發起2個請求。第二種和第三種應該差不多3、最靈活:從靈活性上來看,第三種肯定是最缺乏的,但是其實對於404來說並不是需要經常變化的,不過也保不準可能可以允許使用者自訂404介面等,這裡一、二兩種方式則提供了靈活性。4、通用性:第三種應該是最通用了,而一、二 兩種則要依賴Spring MVC
自訂404頁面沒顯示
Firefox下顯示正常(出現404)~~360正常應該是你的瀏覽器緩衝問題。。。
怎判斷網站是否有自訂404頁面
使用Last-Modified 判斷apache是否自訂404頁面
2011-06-19 23:20
如果Apache沒有自訂404頁面,那麼每次請求的頁面不存在,也就沒有Last-Modified( 因為Last-Modified 就是mtime )。
而如果 自訂了404頁面,那麼 Last-Modified 就是 這個404頁面的 mtime。
如下試試:
root@ming-laptop:~# curl -I -X GET 172.16.1.54/ming.html
HTTP/1.1 404 Not Found
Date: Sun, 19 Jun 2011 15:06:42 GMT
Server: Apache/2.2.19 (Unix) DAV/2
Content-Length: 207
Content-Type: text/html; charset=iso-8859-1
root@ming-laptop:~# curl -I -X GET 172.16.1.54/ming.html
HTTP/1.1 404 Not Found
Date: Sun, 19 Jun 2011 15:08:32 GMT
Server: Apache/2.2.19 (Unix) DAV/2
Last-Modified: Sun, 19 Jun 2011 15:02:39 GMT
ETag: "88022-8-4a611e8e7c1c0"
Accept-Ranges: bytes
Content-Length: 8
Content-Type: text/html; charset=gbk
root@ming-laptop:~#
# 以上分別是沒自訂404頁面和自訂404頁面的返回結果, 可以看到 第一次訪問沒有Last-Modified。
# 這樣就OK
# 註: 使用nginx測試發現 自訂404頁面也沒有Last-Modified。 ( 看樣子以後測試服務端行為,還是使用Apache這個老大 )
參考資料:blog.sina.com.cn/chengyu269