在上一篇日誌中我們看到,配置Spring MVC,當用戶發來一個HTTP請求,前端控制器DispatcherServlet首先會去接收,然後請求處理器映射器HandlerMapping,在處理器映射器中查找可以處理該請求的Handler,得到處理器映射器返回的執行鏈後,前端控制器再根據執行鏈,與處理器適配器HandlerAdapter進行匹配,找到可以處理的Handler,最後執行相關的handler()方法來獲得ModelAndView對象。從這一系列過程來看,處理器映射器和處理器適配器起到了關鍵的作用,它們決定了選擇哪個Handler來處理數據請求。處理器映射器和處理器適配器都有兩種配置方式,非註解和註解的形式,上一篇Spring MVC配置中使用的就是非註解形式,在這篇日誌中我會再總結兩種方式的配置。
非註解形式
非註解形式,也就是把配置信息放在了XML文件中,如把處理器映射器和適配器的信息放在Spring MVC的配置文件springmvc.xml中。
非註解的處理器映射器配置
這裏使用處理器映射器SimpleUrlHandlerMapping來做示例,SimpleUrlHandlerMapping映射器可以讓我們自行配置url和處理器handler之間的映射關係:
<!-- 非註解形式配置處理器映射器 -->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<!-- url映射 -->
<property name="mappings">
<props>
<!-- 將不同的url請求映射響應的Controller處理器 -->
<prop key="/queryUsersTest1.action">userController</prop>
<prop key="/queryUsersTest2.action">userController</prop>
<prop key="/queryUsersTest3.action">userController2</prop>
</props>
</property>
</bean>
<!-- 配置被url映射的Handler -->
<bean id="userController" class="com.mvc.controller.UserControllerTest" />
<bean id="userController2" class="com.mvc.controller.UserControllerTest2" />
在Spring MVC的配置文件springmvc.xml中,配置一個名爲urlMapping的映射器,裏面用prop標籤對配置url請求與Controller控制器的映射關係,我們可以配置不同的url映射同一個控制器,如queryUserTest1和queryUserTest2都對應userController。也可以配置不同url映射不同的控制器,如queryUserTest3對應userController2。最後聲明兩個Controller對應的控制器實現類。
非註解的處理器適配器配置
爲了判斷處理器映射器返回的執行鏈,在處理器適配器中是否有匹配的控制器Handler,還需要配置處理器適配器,非註解方式的處理器適配器,同樣在配置文件springmvc.xml中配置:
<!-- 非註解形式配置處理器適配器 -->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />
示例使用HttpRequestHandlerAdapter,即HTTP請求適配器,負責處理用戶的HTTP請求。既然用到HTTP請求適配器,自然我們需要一個實現HttpRequestHandler接口的Handler控制器。
實現HttpRequestHandler接口控制器
public class UserControllerTest2 implements HttpRequestHandler {
private UserService userService = new UserService();
@Override
public void handleRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// 數據模型Model,模擬獲取用戶信息列表
List<User> userList = userService.queryUserList();
// 設置數據模型
request.setAttribute("userList", userList);
// 設置轉發視圖
request.getRequestDispatcher("/WEB-INF/jsp/users/userList.jsp").forward(request, response);
}
實現HttpRequestHandler接口的Handler處理器中,重寫的handleRequest()方法不需要返回ModelAndView對象,而是設置返回請求參數response的一些參數,如設置其數據模型和視圖,直接配置在了返回請求response中。之後,我們就可以通過訪問地址:
http://localhost:8080/SpringMVC__Project/queryUsersTest1.action
得到請求的數據視圖。
註解形式
使用註解方式的處理器映射器和處理器適配器,在xml文件中代碼量減少了很多,只需要在處理器實現類以及具體Handler方法中使用註解即可。在Spring MVC中的處理器映射器和適配器分別是RequestMappingHandlerMapping和RequestMappingHandlerAdapter。
註解形式的處理器映射器配置
在springmvc.xml配置文件中,使用bean標籤對配置註解的處理器映射器:
<!-- 註解形式的處理器映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
註解形式的處理器映射器會對類中用@RequestMapping標記的方法進行映射。
註解形式的處理器適配器配置
同樣地,使用註解形式的處理器適配器,會把使用@RequestMapping標記的方法與處理器映射器返回的執行鏈進行適配,匹配則執行相應的Handler方法:
<!-- 註解形式的處理器適配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />
以上是註解形式的其中一種配置方式,我們還可以使用簡寫的方式:
<!-- 簡寫方式 -->
<mvc:annotation-driven></mvc:annotation-driven>
這種簡寫方式配置中,會自動註冊RequestMappingHandlerMapping和RequestMappingHandlerAdapter。
註解的Handler控制器實現類
上面說到,使用註解形式配置的處理器映射器和適配器,需要在具體的Handler實現類中使用註解:
// 使用註解的控制器,@Controller標識它是一個控制器
@Controller
public class annotateControllerTest {
private UserService userService = new UserService();
@RequestMapping("/queryUserList")
public ModelAndView queryUserList() {
// 數據模型Model,模擬獲取用戶信息列表
List<User> userList = userService.queryUserList();
// 返回的ModelAndView對象
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("userList", userList);
// 指定視圖View
modelAndView.setViewName("/WEB-INF/jsp/users/userList.jsp");
// 數據處理完後,返回視圖和數據
return modelAndView;
}
在具體的控制器實現類中,使用了@Controller註解這是一個Handler控制器類,這樣該類纔可以被處理器適配器查找到。然後到了具體的實現方法queryUserList()上,有一個註解信息@RequestMapping,註解括號裏指定了一個url請求,也就是該url匹配的是這個Handler方法()。
最後,要在配置文件springmvc.xml中生命這個Handler類,這樣才能讓處理器映射器也找到這個控制器類:
<bean class="com.mvc.controller.annotateControllerTest"></bean>
<!-- 或者使用掃描配置,對包下的所有類掃描 -->
<!-- <context:component-scan base-package="com.mvc.controller"></context:component-scan> -->
聲明的方式有兩種,一種是直接使用bean標籤對聲明該Handler類,不過不推薦這種方式,因爲隨着控制器類越來越多,代碼量也變得越來越多,所以推薦第二種方式,配置掃描包下的控制器類。
所有東西配置完後,就可以重啓Tomcat服務器,訪問地址:
http://localhost:8080/SpringMVC__Project/queryUserList.action
得到訪問結果:
完整代碼已上傳GitHub:
https://github.com/justinzengtm/SSM-Framework/tree/master/SpringMVC_Project