Spring MVC的API:
DispatcherServlet: 整個Spring MVC的前端控制器,由它來接管來自客戶端的請求
HandlerMapping: DispatcherServlet會通過它來處理客戶端請求到各個(Controller)處理器的映射
HandlerAdapter: HandlerMapping會根據它來調用Controller裏需要被執行的方法
HandlerExceptionResolver: spring mvc處理流程中,如果有異常拋出,會交給它來進行異常處理
ViewResolver: HandlerAdapter會把Controller中調用返回值最終包裝成ModelAndView,ViewResolver會檢查其中的view,如果view是一個字符串,它就負責處理這個字符串並返回一個真正的View,如果view是一個真正的View則不會交給它處理,爲什麼view即可以是字符串又會是View呢下面會進行解釋
View: 對應MVC 中的V, 此接口只有一個方法 render,用於視圖展現
ModelAndView 對於解決上面介紹ViewResoler或者下面圖片的疑惑,這個類中的view這個屬性是 Object 類型的,它可以是一個視圖名也可以是一個實際的View,這點我們觀察其源碼可以很清楚的看出來
Spring MVC流程:
1.通過DispatcherServlet攔截用戶請求
2.DispatcherServlet從HandlerMapping映射中獲取用戶請求是到哪個Controller,並把結果返回到DispatcherServlet中
3.請求到達Controller後,執行相關業務,返回ModelAndView到DispatcherServlet中
4.根據ModelAndView從ViewResolver中找到需要顯示的View,並返回到DispatcherServlet中
5.DispatcherServlet把View響應到用戶端
Spring MVC的簡單實現:
web.xml的相關配置
<servlet>
<servlet-name>springServlet</servlet-name>
<!-- Spring MVC的核心控制器(前端控制器)攔截用戶的請求 -->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 開啓服務時初始化,創建相應的Bean -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
創建自己的Controller(後端控制器),繼承AbstractController並實現handleRequestInternal方法
public class LoginAction extends AbstractController {
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request,
HttpServletResponse response) throws Exception {
// TODO Auto-generated method stub
return null;
}
}
applicationContext.xml的相關配置
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- 配置controller的業務Bean -->
<bean id="loginAction" class="com.web.action.LoginAction">
</bean>
<!-- 配置url與controller的映射關係 -->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/login.do">loginAction</prop>
</props>
</property>
</bean>
<!-- 配置視圖View(已jsp作爲視圖) -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
現在如果用戶發送/login.do的請求,請求就會到達LoginAction中進行處理,以及響應客戶端
用以上的相關配置有一點不好的地方就是,用戶的每個請求都需要用一個Controller來處理,要怎麼樣才能實現一個Controller中寫多個處理方法接受用戶不同的請求呢?有以下兩種方式:
方式一:繼承
Controller不再繼承AbstractController類,現在繼承MultiActionController類來實現多方法,處理方式如下
web.xml的相關配置不變,需要重寫LoginAction這個Controller類
package com.web.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
/**
* 繼承AbstractController只能實現一個動作對應一個方法
* 繼承MultiActionController實現一個controller中寫多個方法
* @author Administrator
*
*/
public class LoginAction extends MultiActionController {
private String fromView;
private String toView;
/**
*
* 處理方法的訪問修飾符只能爲public
* @param request
* @param response
* @return
* @throws Exception
*/
public ModelAndView getList(HttpServletRequest request, HttpServletResponse response) throws Exception {
request.setAttribute("list", "執行getList方法成功");
return new ModelAndView(toView);
}
public ModelAndView doLogin(HttpServletRequest request,
HttpServletResponse response) throws Exception {
//獲取表單數據
String username = request.getParameter("username");
String password = request.getParameter("password");
//調用業務邏輯方法
String result = login(username, password);
if("success".equals(result)){
request.setAttribute("result", "成功");
return new ModelAndView(toView);
}else{
request.setAttribute("result", "失敗");
return new ModelAndView(fromView);
}
}
private String login(String username, String password){
if("123".equals(username) && "admin".equals(password)){
return "success";
}
return "fail";
}
public String getFromView() {
return fromView;
}
public void setFromView(String fromView) {
this.fromView = fromView;
}
public String getToView() {
return toView;
}
public void setToView(String toView) {
this.toView = toView;
}
}
applicationContext.xml的相關配置
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- 配置methodNameResolver -->
<bean id="ParameterMethodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
<property name="paramName" value="action"/>
</bean>
<!-- 配置controller的業務Bean -->
<bean id="loginAction" class="com.web.action.LoginAction">
<!-- controller繼承MultiActionController並添加這個配置,使controller能寫多個方法 -->
<property name="methodNameResolver" ref="ParameterMethodNameResolver"/>
<!-- 初始化屬性 -->
<property name="fromView" value="login"/>
<property name="toView" value="index"/>
</bean>
<!-- 配置url與controller的映射關係 -->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/login.do">loginAction</prop>
</props>
</property>
</bean>
<!-- 配置視圖View(已jsp作爲視圖) -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前綴 -->
<property name="prefix" value="/"/>
<!-- 後綴 -->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
用戶發送請求/login.do?action=doLogin或者/login.do?action=getList就會執行相應的處理方法了,這樣就可以訪問了
方式二:註解
web.xml的相關配置不變,需要重寫LoginAction這個Controller類
業務類UserService:添加註解@Service
package com.service;
import org.springframework.stereotype.Service;
/**
* 業務類(M)
* @author Administrator
*
*/
@Service
public class UserService {
public String login(String username, String password){
if("123".equals(username) && "admin".equals(password)){
return "登錄成功";
}
return "登錄失敗";
}
}
Controller類LoginAction:添加註解@Controller
package com.web.action;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.service.UserService;
@Controller
@RequestMapping("/login")
public class LoginAction {
@Autowired
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
/**
* @param username
* @param password
* @return
* 返回ModelAndView,並使用map傳遞數據到頁面
*/
@RequestMapping("/doLogin.do")
public ModelAndView doLogin(String username, String password) {
String result = userService.login(username, password);
Map<String, Object> map = new HashMap<String, Object>();
map.put("result", result);
if("登錄成功".equals(result)){
return new ModelAndView("index",map);
}
return new ModelAndView("login",map);
}
/**
* @param request
* @return
* 返回String,使用request傳遞數據到頁面
*/
@RequestMapping("/getList.do")
public String getList(HttpServletRequest request){
request.setAttribute("result", "執行GetList方法成功");
return "/index";
}
}
applicationContext.xml的相關配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<!-- 自動掃描路徑下的所有文件,並根據註解完成注入的工作 -->
<context:component-scan base-package="com.service,com.web.action"/>
<!-- 默認的註解映射的支持 -->
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<!-- 啓動Spring MVC的註解功能,完成請求和註解POJO的映射 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<!-- 使spring支持註解 -->
<context:annotation-config/>
<!-- 配置視圖View(已jsp作爲視圖) -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
用戶請求:
<a href="login/getList.do">點擊獲取List</a>
<form action="login/doLogin.do" method="post"></form>,訪問成功。
但是存在以下疑點:
在applicationContext.xml配置中,我刪除以下配置仍可正常運行...
<!-- 默認的註解映射的支持 -->
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<!-- 啓動Spring MVC的註解功能,完成請求和註解POJO的映射 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<!-- 使spring支持註解 -->
<context:annotation-config/>