HTTP請求被DispatcherServlet攔截後,會調用HandlerMapping來處理,HandlerMapping根據 url<=>controller 之間的映射關係來肯定要調用哪一個controller來處理。java
有2種HandlerMapping:web
BeanNameUrlHandlerMappingspring
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /> <bean name="/userController" class="com.chy.controller.UserController" />
http://localhost:8080/springmvc_war_exploded/userController
BeanNameUrl,顧名思義,映射關係是BeanName <=> Url,url地址對應bean的name,根據url中的beanname肯定要調用的controller。瀏覽器
SimpleUrlHandlerMappingmvc
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <!-- 使用props配置url-controller之間的映射關係 --> <props> <!-- 一個prop配置一個映射,key指定url,value指定bean的id或name。可以使用多個prop。 --> <prop key="/userController">userController</prop> </props> </property> </bean> <bean name="userController" class="com.chy.controller.UserController" />
http://localhost:8080/springmvc_war_exploded/userController
url是/userController,去<props>中找到key=/userController的<prop>,獲得要調用的controller的name或id。app
HandlerMapping肯定要調用的controller後,將要調用的controller告訴DispatcherServlet,jsp
由DispatcherServlet調用controller所屬的HandlerAdapter,再由HandlerAdapter來調用controller。ide
HandlerAdapter有2種:url
SimpleControllerHandlerAdapter(推薦)spa
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
public class UserController implements Controller { @Override public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception { //視圖能夠在構造器中指定,也能夠先使用空參構造器,在調用setter方法設置 ModelAndView mav = new ModelAndView("user_info"); User user = new User(); user.setUsername("chy"); user.setPassword("abcd"); //向視圖傳遞數據 mav.addObject("user", user); return mav; } }
SimpleControllerHandlerAdapter,名字中有Controller,實現的天然是Controller接口。
方法要返回一個ModelAndView類型的值。
這個ModelAndView由controller返回給HandlerAdapter,再由HandlerAdapter返回給DispatcherServlet。
DispatcherServlet調用配置的ViewResolver來解析ModelAndView,獲取裏面的model(數據)、view(視圖名),並將數據、視圖名返回給DispatcherServlet。
DispatcherServelt對View進行渲染(把模型數據填入視圖中),把渲染好的視圖返回個瀏覽器。
因此須要搭配ViewResolver使用:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前綴--> <property name="prefix" value="/WEB-INF/jsp/" /> <!--後綴--> <property name="suffix" value=".jsp" /> </bean>
視圖解析器也有好幾種,此處再也不一一介紹。
HttpRequestHandlerAdapter
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />
public class UserController implements HttpRequestHandler{ @Override public void handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException { User user = new User(); user.setUsername("chy"); user.setPassword("abcd"); //向視圖傳遞數據 httpServletRequest.setAttribute("user",user); //將請求轉發到視圖(地址欄的url不變) RequestDispatcher dispatcher = httpServletRequest.getRequestDispatcher("/WEB-INF/jsp/user_info.jsp"); dispatcher.forward(httpServletRequest,httpServletResponse); } }
適配器與實現的接口是對應的。使用請求轉發實現,返回值是void。
ViewResolver是解析ModelAndView用的,既然返回值是void,就不使用視圖解析器,沒有視圖名的拼接,須要寫視圖的完整路徑。
此種方式是Servlet的實現方式,不建議使用。儘可能使用ModelAndView的方式,更加符合mvc的思想。