org.springframework.web.servlet.mvc.AbstractController (implements org.springframework.web.servlet.mvc.Controller)
Spring MVC框架中的Controller對請求進行處理:所有的Controller都實現(xiàn)接口Controller:
public interface Controller {
/**
* Process the request and return a ModelAndView object which the DispatcherServlet
* will render. A <code>null</code> return value is not an error: It indicates that
* this object completed request processing itself, thus there is no ModelAndView
* to render.
* @param request current HTTP request
* @param response current HTTP response
* @return a ModelAndView to render, or <code>null</code> if handled directly
* @throws Exception in case of errors
*/
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
上面的doc表明Controller返回的modelandview可以使空,表明請求都是該函數(shù)中處理完成了,不需要modeland來進行渲染。
在繼續(xù)之前先介紹一個有用的工具類:WebUtils。用這個可以簡化session,request的處理。具體的內(nèi)容可以參考文檔。
Controller的第一個實現(xiàn)是:AbstractController。他是一個Abstract類,除了實現(xiàn)了Controller接口,它還繼承了WebContentGenerator。
WebContentGenerator的作用是什么?參考文檔可以發(fā)現(xiàn),該類主要對Cache和Session進行管理。
cacheSeconds |
指定內(nèi)容緩存的時間,默認為1 |
requireSession |
是否需要會話,默認支持 |
supportedMethods |
支持的方法,默認是GET\post\Head |
useCacheControlHeader |
指定是否使用http1.1的cache控制頭信息,默認使用 |
useCacheControlNoStore |
指定是否設(shè)置http1.1的cache控制頭信息為no-store。默認使用 |
useExpiresHeader |
指定是否使用http1.0的expire頭信息。默認使用 |
用戶可以對這些參數(shù)進行測試,cache和expire信息涉及到了http協(xié)議信息,更多信息可以參考http協(xié)議文檔。這里不再說明。
再看AbstractController的代碼:
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// Delegate to WebContentGenerator for checking and preparing.
checkAndPrepare(request, response, this instanceof LastModified);
// Execute handleRequestInternal in synchronized block if required.
if (this.synchronizeOnSession) {
HttpSession session = request.getSession(false);
if (session != null) {
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
return handleRequestInternal(request, response);
}
}
}
return handleRequestInternal(request, response);
}
checkandPrepare的目的就是使用用于進行的配置來對request進行預(yù)處理和準備。
他會檢查支持的方法,和會話,然后應(yīng)用cache設(shè)置。
如果需要session同步,就進行同步處理。session同步應(yīng)用于有session的情況下。如果沒有session,session同步是沒有用的。
AbstractController會調(diào)用handleRequestInternal方法進行處理,繼承AbstractController的類需要實現(xiàn)該方法。
下面我們再看看AbstractUrlViewController 的代碼實現(xiàn)和文檔,先看handleRequestInternal的實現(xiàn):
/**
* Retrieves the URL path to use for lookup and delegates to
* {@link #getViewNameForRequest}.
*/
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
String viewName = getViewNameForRequest(request);
if (logger.isDebugEnabled()) {
logger.debug("Returning view name '" + viewName + "' for lookup path [" + lookupPath + "]");
}
return new ModelAndView(viewName);
}
可以看到,它使用了getViewNameForRequest獲取需要的viewName。而getViewNameForRequest是一個抽象函數(shù),需要子類實現(xiàn)。lookupPath就是我們請求的URL中的一部分。如我們使用UrlFilenameViewController來進行如下的配置:
<bean name="/index.do" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"></bean>、
09-11-25 11:56:06 - DEBUG [http-8200-1] - Returning view name 'index' for lookup path [/index.do]
該Controller對/index.do解析成index,然后再通過viewResolver對index進行擴展為/jsp/index.jsp。從而找到該頁面。
可以看到這個類的主要是用于對url進行解析,然后轉(zhuǎn)到合適的頁面上,而在轉(zhuǎn)到這個頁面之前不需要進行特別的處理。
明白了該類的作用自然也就知道了UrlFilenameViewController的作用。這里不再進行詳細分析。