類圖
InternalResourceView類圖
屬性
結(jié)合InternalResourceView及其父類婆赠,我們可以發(fā)現(xiàn)它有如下一些屬性:
String beanName;
String contentType = "text/html;charset=ISO-8859-1";
String requestContextAttribute;
Map<String, Object> staticAttributes = new LinkedHashMap<String, Object>(); // 靜態(tài)屬性休里,會(huì)與model進(jìn)行合并
exposePathVariables = true; // 決定請(qǐng)求路徑中的變量是否與合并到model中
String url;
boolean alwaysInclude = false; // 如果為true赃承,則總是調(diào)用RequestDispatcher的include方式
boolean exposeContextBeansAsAttributes = false; // 決定是否將context中的beans作為屬性暴露
Set<String> exposedContextBeanNames; // 決定需要暴露的beans的名稱
boolean preventDispatchLoop = false; // 決定是否允許循環(huán)循環(huán)
渲染流程
整合InternalResourceView及其父類的渲染部分瞧剖,
// AbstractView
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
if (logger.isTraceEnabled()) {
logger.trace("Rendering view with name '" + this.beanName + "' with model " + model +
" and static attributes " + this.staticAttributes);
}
Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);
prepareResponse(request, response); // 用來解決IE的https下載的bug
renderMergedOutputModel(mergedModel, request, response);
}
// InternalResourceView
protected void renderMergedOutputModel(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
// Determine which request handle to expose to the RequestDispatcher.
HttpServletRequest requestToExpose = getRequestToExpose(request);
// Expose the model object as request attributes.
exposeModelAsRequestAttributes(model, requestToExpose);
// Expose helpers as request attributes, if any.
exposeHelpers(requestToExpose);
// Determine the path for the request dispatcher.
String dispatcherPath = prepareForRendering(requestToExpose, response);
// Obtain a RequestDispatcher for the target resource (typically a JSP).
RequestDispatcher rd = getRequestDispatcher(requestToExpose, dispatcherPath);
if (rd == null) {
throw new ServletException("Could not get RequestDispatcher for [" + getUrl() +
"]: Check that the corresponding file exists within your web application archive!");
}
// If already included or response already committed, perform include, else forward.
if (useInclude(requestToExpose, response)) {
response.setContentType(getContentType());
if (logger.isDebugEnabled()) {
logger.debug("Including resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
}
rd.include(requestToExpose, response);
}
else {
// Note: The forwarded resource is supposed to determine the content type itself.
if (logger.isDebugEnabled()) {
logger.debug("Forwarding to resource [" + getUrl() + "] in InternalResourceView '" + getBeanName() + "'");
}
rd.forward(requestToExpose, response);
}
}
我們可以分析整個(gè)處理流程如下做粤,
- 進(jìn)行model合并(將靜態(tài)屬性捉撮、地址變量和原model合并呕缭,與staticAttributes和exposePathVariables屬性有關(guān))
- 將請(qǐng)求處理器暴露給RequestDispatcher(與exposeContextBeansAsAttributes和exposedContextBeanNames屬性有關(guān))
- 將合并后的model作為屬性暴露給請(qǐng)求
- 將helper作為請(qǐng)求屬性暴露
- 設(shè)置路徑(這里主要是做了一個(gè)url循環(huán)判斷恢总,與preventDispatchLoop屬性的設(shè)置有關(guān))
- 獲取請(qǐng)求睬愤、路徑對(duì)應(yīng)的RequestDispatcher
- 通過include或forward進(jìn)行請(qǐng)求處理