Spring MVC實現一個控制器寫多個方法(註解方式、繼承方式)

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/>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章