要自定義視圖首先創建一個實現View接口的類,添加@Component註解。如下,
@Component
public class ToView implements View{
public String getContentType() {
return "text/html";
}
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
throws Exception {
PrintWriter out = response.getWriter();
out.print("hello");
out.flush();
out.close();
}
}
然後再Spring配置文件裏添加視圖解析器配置,設置優先級爲0;
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" p:order="0"></bean>
Controller定義Handler方法,該方法返回自定義視圖的名字(默認情況下爲首字母小寫的類名)
@Controller
public class UserInfoController {
@RequestMapping("/userinfo/toView.do")
public String toView() {
return "toView";
}
}
此時自定義視圖配置完畢。
而當一個請求進入 DispatcherServle ,他都會進入該類中的 doDispath
在向下執行至下圖第一個紅框處,當該行方法執行之後。意味着 HandleMethod 方法已經執行完畢了。這時mv裏面已經保存了視圖的名字和返回的數據。
然後向下執行至 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); 進入,在下圖的第一個紅框處檢查是否有異常。
然後進入 render(mv, request, response); 方法,我們在下圖第一個紅框處進行視圖解釋。
進入view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request); 方法。
此時我們進入debug 模式運行。可以看到viewResolvers裏面有兩個視圖,其中一個就是我們自定義的視圖。因爲我們給該視圖設置了優先級,所以BeanNameViewResolver 在第一個,優先從容器中得到這個。
然後我們再去找該viewResolver.resolveViewName(viewName, locale)類實現的接口
此時我們可以看出該返回值 根據視圖名直接從IOC容器中獲取視圖對象。
執行完畢後,返回到上面的 render方法執行 view.render(mv.getModelInternal(), request, response);此時。該render方法執行的我們自定義視圖中的render方法。
自定義視圖功能得以實現。