對springMVC的深入認識

1、MVC設計模式(這裏講的是b/s情況下的模式)


2、springMVC框架與spring的關係

springMVC只是spring框架的一個模塊;如下圖是spring整個框架的內容:


3、springMVC的框架結構原理


1、 用戶發起請求,請求到DispatcherServlet前端控制器

DispatcherServlet(中央調度),負責requestresponse,負責調用處理器映射器查找Handler,負責調用處理器適配器執行Handler,有了前端控制器降低了各各組件之間的耦合性,系統擴展性提高。

2、 DispatcherServlet前端控制器請求處理器映射器HandlerMapping查找Handler

根據用戶請求的url,根據一定的規則去查找(比如:xml配置,註解)

3、 HandlerMapping處理器映射器將Handler返回給前端控制器

4、 DispatcherServlet前端控制器調用HandlerAdapter處理器適配器執行Handler

程序員編寫的Handler是按照適配器要求的規則去執行Handler

 

5、 HandlerAdapter處理器適配器執行Handler

適配器按照一定規則去執行Handler

6、 Handler執行完成,返回ModelAndView

ModelAndViewspringmvc的封裝對象,將modelview封裝在一起。

7、 HandlerAdapter處理器適配器將ModelAndView返回給前端 控制器

 

8、 前端控制器調用視圖解析器,進行視圖解析,解析完成給前端控制器返回View

Viewspringmvc的封裝對象,是一個接口,實現類包括jspviewpdfview。。。。

9、 前端控制器調用view進行視圖渲染

將模型數據填充到view(將model數據填充到request)響應給用戶

10、前端控制器響應給用戶。

4、這裏詳細的說明一下springmvc平常要了解的(開發是不常用的,一般都是用註解)三大組件:

1、處理器映射器常用的兩個是(在註解開發中就是指的requestMapping註解):


<!-- 處理器映射器 根據url匹配bean的name 處理器映射器實現了HandlerMapping接口 -->
	<bean
		class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />

	<!-- 簡單url映射的處理器映射器 -->
	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/hello1.action">hello_controller</prop>
				<prop key="/hello2.action">hello_controller</prop>
				<prop key="/hello3.action">hello_controller3</prop>
			</props>
		</property>
	</bean>

對應的controller類的配置:

        <!-- 配置action -->
	<bean id="hello_controller" name="/helloworld.action" class="cn.itcast.springmvc.Hello" />
	
	<!-- 配置action -->
	<bean id="hello_controller3"  class="cn.itcast.springmvc.Hello1" />


根據處理器映射器就可以找到對應的handler(函數)

package cn.itcast.springmvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

/**
 * 
 * <p>Title: Hello</p>
 * <p>Description: 使用SimpleControllerHandlerAdapter適配器</p>
 * <p>Company: www.itcast.com</p> 
 * @author	
 * @version 1.0
 */
public class Hello implements Controller {

	@Override
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		
		ModelAndView modelAndView = new ModelAndView();
		
		modelAndView.addObject("message", "helloworld!!!!!!");
		
		//響應到jsp的邏輯試圖
		
		//modelAndView.setViewName("/WEB-INF/jsp/hello.jsp");
		
		return modelAndView;
	}

}

2、瞭解兩個處理器適配器(實際上就是我們在使用springmvc的controller註解)

        <!-- 處理器適配器 實現了HandlerAdapter接口 action按照適配器要求開發 ,規則是實現Controller接口 -->
	<bean
		class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

	<!-- 配置HttpRequestHandlerAdapter處理器適配器 -->
	<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />

使用不同的適配器在MVC的C層的類需要實現不同的接口

使用SimpleControllerHandlerAdapter適配器,就要使用SimpleControllerHandlerAdapter適配器的規則進行處理

/**
 * 
 * <p>Title: Hello</p>
 * <p>Description: 使用SimpleControllerHandlerAdapter適配器</p>
 * <p>Company: www.itcast.com</p> 
 * @author	
 * @version 1.0
 */
public class Hello implements Controller {

	@Override
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		
		ModelAndView modelAndView = new ModelAndView();
		//下面的方法就相當於request.setAttribute("message", message);
		modelAndView.addObject("message", "helloworld!!!!!!");
		return modelAndView;
	}


}


使用 使用HttpRequestHandlerAdapter適配器,就要使用HttpRequestHandlerAdapter適配器的規則進行處理
/**
 * 
 * <p>Title: Hello1</p>
 * <p>Description: 使用HttpRequestHandlerAdapter</p>
 * <p>Company: www.itcast.com</p> 
 * @version 1.0
 */

public class Hello1 implements HttpRequestHandler {

	@Override
	public void handleRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		//向頁面顯示一行提示信息
		String message = "hellworld1";
	    request.setAttribute("message", message);
	    
	    //指定轉向頁面,使用request指定頁面完整路徑
	    request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(request, response);
		
	}

}

3、視圖解析器

<!-- 視圖解析器 解析jsp視圖,默認使用jstl,要求classpath下有jstl的jar包 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- 視圖的前綴 -->
		<property name="prefix" value="/WEB-INF/jsp/" />
		<!-- 視圖的後綴 -->
		<property name="suffix" value=".jsp" />

	</bean>

這樣使用視圖解析器,就可以在controller層直接使用邏輯視圖名稱進行頁面的響應:

modelAndView.setViewName("hello");

這裏可以參考git倉庫資源中的源碼:點擊打開鏈接


5、針對springMVC在平常的開發中註解使用如下:

1、@controller

標識該類爲控制器類,@controller@service@repository分別對應了web應用三層架構的組件即控制器、服務接口、數據訪問接口

2、 @RequestMapping

進行url映射,一個方法對應一個url,定義方法:在action方法上定義requestMapping


3、在平常的開發中會使用 根路徑+子路徑 來辨別action的URL



4、 URI模板模式映射

(使用url的模板式映射的思想是:讓每一條資源數據都有唯一的一個URL路徑)


5、請求方法限定


可以限定爲getpost、或兩者都可以

限定GET方法

@RequestMapping(method = RequestMethod.GET)

如果通過Post訪問則報錯:

HTTP Status 405 - Request method 'POST' not supported

 

例如:

@RequestMapping(value="/useredit/{userid}",method=RequestMethod.GET)

限定POST方法

@RequestMapping(method = RequestMethod.POST)

如果通過Post訪問則報錯:

HTTP Status 405 - Request method 'GET' not supported

 

GETPOST都可以

@RequestMapping(method={RequestMethod.GET,RequestMethod.POST})

6、springMVC的請求參數綁定(重點)

這裏請求的參數綁定在handler處理器的形式參數中(Springmvc通過參數解析器,將客戶端請求的key/value解析成方法形參數);

參數解析器

Spring提供了很多參數解析器,將key/value的數據解析成形參,通過反射解析method中的參數(類型、名稱),按照類型和名稱規則解析形參;

屬性編輯器:

key/value轉換成pojo中的屬性

6.1 默認支持的參數類型

 

  • HttpServletRequest
  • 通過request對象獲取請求信息
  • HttpServletResponse
  • 通過response處理響應信息
  • HttpSession
  • 通過session對象得到session中存放的對象
  • Model
  • 通過model向頁面傳遞數據,如下:
  •  
  • model.addAttribute("user",new User("李四"));
  •  
  • model也可以通過modelMapmap將數據傳到頁面。

6.2 表單對象-簡單數據類型

 

Action方法的形參數默認支持:stringintdouble等簡單類型,建議使用包裝類型(可以設置null)。

注意:對於date類型的參數需要註冊屬性編輯器。

 

使用方法:

直接在形參上定義

也可以在pojo中通過屬性傳遞簡單類型


6.3表單對象-pojo類型

第一種,不需要封裝目標bean



第二種需要對bean封裝一次



6.4 字符串數組綁定



6.5、 List綁定參數類型

頁面向action傳遞複雜的批量數據,比如學生的成績信息(課程名稱、成績)

頁面定義:


Scores:包裝對象中list屬性的名稱

Coursename:包裝對象中listpojo的屬性名稱。

Score:包裝對象中listpojo的屬性名稱。

如果上邊下標相同的CoursenameScore設置在一個pojo中。

 

 

Action方法定義:

使用List<pojo>接收上邊的接收,pojo中包括上邊課程名稱(coursename)和成績(score)


6.6、 @RequestParam綁定單個請求參數

value參數名字,即入參的請求參數名字,如value=“studentid表示請求的參數區中的名字爲studentid的參數的值將傳入;

required是否必須,默認是true,表示請求中一定要有相應的參數,否則將報400錯誤碼;

defaultValue默認值,表示如果請求中沒有同名參數時的默認值

 

需求

學生查詢方法中必須要有一個參數group(學生分組)

 

實現:

 




7、 springMVC中結果轉發


Redirect:請求重定向

瀏覽器中地址欄的url通過Redirect變了,重新定義了一個request

Action方法通過Redirect重定向到另一個方法,方法形參無法帶到另一個方法。

定義方法:

 

//請求重定向
return "redirect:querystudent.action";

Forward:頁面轉發

瀏覽器中地址欄的url通過Forward不變,沒有重新定義了一個request

    Action方法通過Forward轉發到另一個方法,方法形參可以帶到另一個方法。

 

定義方法:

 

//頁面轉發
return "forward:querystudent.action";


8、springMVC中 @RequestBody @ResponseBody註解實現json數據交互

Json數據在企業中使用好處:

Json在企業開發中已經作爲通用的接口參數類型。

Json數據在頁面(客戶端)解析很方便。

 

Json定義:

var obj=name”:”張三”,”age”:12//key/value格式

Json數據解析:

obj.name


在處理器適配器上配置json的解析器,原因是處理器適配器處理handler

配置

<!--註解適配器 -->
	<!-- <bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		json轉換器
		<property name="messageConverters">
			<list>
				<bean
					class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
			</list>
		</property>

	</bean> -->
controller層

/**
 * 
 * <p>Title: JsonAction</p>
 * <p>Description: json轉換測試</p>
 * <p>Company: www.itcast.com</p> 
 * @author	傳智.燕青
 * @date	2014-12-15下午5:38:43
 * @version 1.0
 */
@Controller
public class JsonAction {
	
	//請求json響應json
	@RequestMapping("/requestJson")
	public @ResponseBody Student requestJson(@RequestBody Student student)throws Exception{
		
		System.out.println(student);
		return student;
	}
	
	
	//請求key/value響應json
	@RequestMapping("/responseJson")
	public @ResponseBody Student responseJson(Student student)throws Exception{
		
		System.out.println(student);
		return student;
	}

}


9、springMVC的攔截器

 

攔截器是針對handlerMapping的攔截器,由handlerMapping查找Handler後,將攔截器返回給前端控制器(DispatcherServlet)。


間接配置全局攔截器:讓springmvc框架自動向每個handlerMapping中註冊攔截器

<!--攔截器 -->
	<mvc:interceptors>
		<!--多個攔截器,順序執行 -->
		<!-- <mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean class="cn.itcast.springmvc.interceptor.HandlerInterceptor1"></bean>
		</mvc:interceptor>
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean class="cn.itcast.springmvc.interceptor.HandlerInterceptor2"></bean>
		</mvc:interceptor> -->
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean class="cn.itcast.springmvc.interceptor.LoginInterceptor"></bean>
		</mvc:interceptor>
		
	</mvc:interceptors>

定義攔截器
實現HandlerInterceptor接口。

public class HandlerInterceptor1 implements HandlerInterceptor {

	//handler,springmvc根據url找到Handler(只有一個方法)
	//執行時機:進入Handler方法之前執行,如果返回false表示攔截,如果返回true表示放行
	//使用場景:用於用戶身份校驗,用戶權限攔截校驗
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		
		System.out.println("HandlerInterceptor1..preHandle");
		
		return false;
	}
	//執行時機:進入Handler方法之後 ,在返回modelAndView之前 
	//使用場景:使用modelAndView,向頁面傳遞通用數據,使用統一的view
	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("HandlerInterceptor1..postHandle");
		
	}
	//執行時機:Handler方法執行完成,(modelAndView已經返回)
	//使用場景:統一異常處理,統一記錄系統日誌,用於action方法執行監控(在preHandle記錄一個時間點,在afterCompletion記錄執行結束時間點,將結束時間點減去開始執行時間點,得到執行時長)
	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("HandlerInterceptor1..afterCompletion");
		
	}


10、springmvc驅動



<!--註解映射器 -->
	<!-- <bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" /> -->
	<!--註解適配器 -->
	<!-- <bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		json轉換器
		<property name="messageConverters">
			<list>
				<bean
					class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
			</list>
		</property>

	</bean> -->
	
	<!-- 使用<mvc:annotation-driven />替換上邊定義的處理器映射器和適配器 並且默認是支持@RequestBody @ResponseBody這兩個註解的--> 										<mvc:annotation-driven />
參考代碼案例:點擊打開鏈接






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