1. 程式人生 > >Java學習筆記——SpringMVC框架

Java學習筆記——SpringMVC框架

一、註解

@RequestMapping:此註解可以放在方法和類上面,用於用於對映url到控制器類或一個特定的處理程式方法,若用在類上,則此類所有處理請求的方法都以該地址作為父路徑。還有各種屬性

	/**
	 * @RequestMapping有8個屬性
	 * 	value:訪問路徑,若只有value屬性可以省略不寫value,例@RequestMapping("/t")
	 * 	method:接受訪問的請求方式有GET、POST、PUT、DELETE等。
	 * 	params:是表明處理請求必須的引數
	 * 	headers:表明處理請求的請求頭引數
	 * 	consumes:指定處理請求的提交內容型別(Content-Type),例如application/json, text/html
	 * 	produces:指定返回的內容型別,僅當request請求頭中的(Accept)型別中包含該指定型別才返回;
	 * 
	 * */
	@RequestMapping(value="/t",method=RequestMethod.GET,params={"name","age!=12"},
		headers={"Accept-Language=en-US,zh;q=0.8"},consumes={"application/json"},produces={})
	public String t(){
		System.out.println(2);
		return "success";
	}

@PathVariable

/**
	 * @PathVariable:SpringMVC向rest風格發展的標誌。
	 * */
		@RequestMapping("/t1/{id}")
		public String t1(@PathVariable("id")Integer id){
			System.out.println(id);
			return "success";
		}

 

   @RequestParam

/**
	 * @RequestParam:獲取請求引數
	 * 	required設定非必要引數
	 * 	defaultValue設定預設引數值
	 * 	注意:若required為false時要把int設定成Integer型別或者設定defaultValue值,
	 * 	否則丟擲IllegalStateException異常
	 * */
		@RequestMapping("/t2")
		public String t2(@RequestParam("id")Integer id,
				@RequestParam(value="name",required=false/*,defaultValue="0"*/)int name){
			System.out.println(id);
			System.out.println(name);
			return "success";
		}

   @RequestHeader

/**
	 * @RequestHeader:獲取請求頭引數
	 * */
		@RequestMapping("/t3")
		public String t3(@RequestHeader(value="Accept-Language")String s1){
			System.out.println(s1);		//輸出結果為:	zh-CN,zh;q=0.8
			return "success";
		}

   @CookieValue

/**
	 * @CookieValue:獲取Cookie各屬性值
	 * */
		@RequestMapping("/t4")
		public String t4(@CookieValue("JSESSIONID")String s1){
			System.out.println(s1);		
			return "success";
		}

 

              @SessionAttributes:講資料放到session域裡面

              @ModelAttribute:被此註解標記的方法會在每個目標方法執行之前先被呼叫一次!(但內部實行原理較複雜,可以參考尚矽谷SpringMVC第20集)

                @ControllerAdvice:修飾處理異常的類。 

                @ResponseStatus:自定義異常類,可以標註類或者方法上。

@ResponseStatus(reason="異常",value=HttpStatus.NOT_FOUND)
public class FirstException extends RuntimeException{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
}
		//@ResponseStatus(reason="異常two",value=HttpStatus.NO_CONTENT)
		@RequestMapping("/t12")
		public String t12(@RequestParam("num")int num){
			System.out.println(1);
			if(num==1){
				System.out.println(2);
				throw new FirstException();
			}
			System.out.println("FirstException");
			return "success";
		}

二、SpringMVC的應用

1、SpringMVC支援pojo入參,若一個表單中各個屬性有與之相配的實體類。可以直接將實體類入參,SpringMVC會自動將表單中各個引數封裝到實體類中去。例:

2、增刪改查對應著post、delete、put、get,因為表單只能提交為post和get,使用hidden隱藏域、name=“_method”,新增HiddenHTTPMethodFilter過濾器把post請求轉化為delete或put請求

3、SpringMVC支援原生servletAPI

4、ModelAndView、Map處理模型資料(ModelMap也一樣)

/**
	 * Map處理模型資料
	 * */
		@RequestMapping("/t6")
		public String t6(Map<String, Object> map){
			map.put("time", new Date());
			return "success";
		}
/**
	 * ModelAndView處理模型資料
	 * */
		@RequestMapping("/t5")
		public ModelAndView t5(){
			ModelAndView modelAndView=new ModelAndView("success");
			modelAndView.addObject("time", new Date());	
			return modelAndView;
		}

        5、國際化資源

                1、首先要在配置檔案中配置ResourceBundleMessageSource類來處理國際化資原始檔。

                2、在src目錄下建立資原始檔

                          

         6、WEB-INF下的檔案是不能被直接訪問的,但有時候我們也需要直接訪問一些頁面,例如登入註冊頁面。這是就可以   用<mvc:view-controller path="/q" view-name="q"/>標籤,不過該標籤需要和<mvc:annotation-driven></mvc:annotation-driven>標籤一起用。 

<!-- 配置直接轉發頁面 -->
	<!-- 可以直接轉發的頁面,無需經過Handler的方法 -->
	<mvc:view-controller path="/q" view-name="q"/>
	
	<mvc:annotation-driven></mvc:annotation-driven>

         7、 SpringMVC可以自定義檢視,可以整合Excel,jsp等檢視技術。只要配置BeanNameViewResolver類,order值越小,優先順序越高,InternalResourceViewResolver的order為 Integer.MAX_VALUE。檢視類實現View介面。介面return返回值只需寫上檢視類的首字母小寫全稱就可以了。

<!-- 第四步:建立jsp試圖解析器 -->
	<bean id="jspResourceViewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
	
	<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
		<property name="order" value="100"></property>
	</bean>
@Component
public class HelloView implements View {
	@Override
	public String getContentType() {
		return "text/html";
	}
	@Override
	public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		response.getWriter().print("hello"+new Date());
	}
}
		@RequestMapping("/t9")
		public String t9(){
			System.out.println("t9");
			return "helloView";
		}

           8、SpringMVC重定向可以在return "redirect:/namespace/toController";轉發:return "forward:/namespace/toController";

           9、SpringMVC型別轉換自定義轉換類繼承org.springframework.core.convert.converter類,並註冊為Spring成員。

           配置ConversionServiceFactoryBean,並在<mvc:annotation-driven>的注入屬性conversion-service,屬性值是ConversionServiceFactoryBean   Bean的id值。

          10、mvc:annotation-driven   標籤

      在配置檔案中配置<mvc:annotation-driven>會自動註冊三個Bean。RequestMappingHandlerMapping與RequestMappingHandlerAdapter兩個Bean,這是Spring MVC為@Controller分發請求所必需的,並且提供了資料繫結支援。

             11、資料格式化。時間、數字等可以直接在實體類欄位上面添加註解,時間用@DateTimeFormat、數字用@NumberFormat,若想自定義型別和SpringMVC提供的型別轉換同時生效則要把ConversionServiceFactoryBean換成FormattingConversionServiceFactoryBean。                                         

 

                  12、資料校驗,加入jsr 303資料驗證jar包,然後在需要資料驗證的bean類欄位上加上需要驗證的註解。在介面上bean類入參前面要加上@Vaild註解,SpringMVC會自動把錯誤資訊放到BindingResult裡面。 

	@Min(100)
	@NumberFormat(pattern="#,###,###.#")
	private Integer id;
	
	@NotEmpty
	private String age;
	
	@NotNull
	private String name;
	
	@DateTimeFormat(pattern="yyyy-mm-dd")
	private Date brith;
	
	@Email
	private String Email;
		@RequestMapping("/t10")
		public String t10(@Valid User user,BindingResult result){
			System.out.println(user);
			if(result.getErrorCount()>0){
				System.out.println("error!");
				
				for(FieldError fieldError:result.getFieldErrors()){
					System.out.println(fieldError.getField()+"---"+fieldError.getDefaultMessage());
				}
			}
			return "success";
		}

                   13、返回json資料,加入三個jar包,然後再介面上加上@ResponseBody註解,返回值直接為資料集合。返回值為byte[]陣列可以實現下載的效果。                                                                                  

                   14、SpringMVC檔案上傳利用 MultipartResolver介面,SpringMVC自身沒有提供上傳實現,利用Apache的commons-fileupload-1.3.1.jar和commons-io-2.4.jar,表單的file名字和入參的@RequestParam的屬性值要一致。 

                   

                   15、SpringMVC攔截器,<mvc:mapping path="/test/*" />可以配置攔截器的作用範圍。攔截器的作用順序跟在配置檔案中的配置順序有關,preHandle方法執行順序是配置檔案中的正序,postHandle和afterCompletion方法的配置檔案中的反序。

public class FirstInterceptor implements HandlerInterceptor{
	/**
	 * 		方法在目標方法渲染檢視之後執行方法。
	 * */
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("FirstInterceptor   -    "+"afterCompletion");
	}

	/**
	 * 		方法在目標方法之後,渲染檢視之前執行。
	 * 		入參屬性中有ModelAndView,可以對請求域中的屬性或檢視做出修改。
	 * */
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("FirstInterceptor   -    "+"postHandle");
	}

	/**
	 * 		方法在目標方法之前執行
	 * 		返回true,後續的攔截器會被繼續執行。
	 * 		返回false,後續的攔截器不會被繼續執行。
	 * */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
		System.out.println("FirstInterceptor   -    "+"preHandle");
		return true;
	}
}
<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<property name="maxUploadSize" value="104857600" />
		<property name="maxInMemorySize" value="4096" />
		<property name="defaultEncoding" value="UTF-8"></property>
		<!-- <property name="uploadTempDir" value="fileUpload/temp"></property> -->
	</bean>

     若第一個攔截器返回的是true,第二個返回的是false時。

                     16、SpringMVC異常處理

        ①、在當前Handler中新增異常處理方法使用@ExceptionHandler註解修飾,並傳入異常類。

        ②、@ExceptionHandler方法中的入參不可以傳入Map中。若想把異常傳到頁面上則需要用到ModelAndView物件。           

        ③、@ExceptionHandler方法標記的異常有優先順序的問題,與發生的異常匹配度越高優先順序越高。也可以寫專門處理異常的類,使用@ControllerAdvice註解來修飾類,若在當前Handler找不到匹配的異常處理(當前Handler中的@ExceptionHandler方法異常類是發生異常的父類,也會找到當前Handler的方法處理異常,即只有當前Handler沒有與之匹配的異常類才會去找@ControllerAdvice修飾的類處理異常),則會去被@ControllerAdvice修飾的類中找匹配的異常處理方法來處理異常。

		@ExceptionHandler(ArithmeticException.class)
		public ModelAndView handlerException(Exception ex){
			System.out.println(ex);
			ModelAndView modelAndView=new ModelAndView("error");
			modelAndView.addObject("exception",ex);
			return modelAndView;
		}
	
		@RequestMapping("/t11")
		public String t11(@RequestParam("num")int num){
			int i=10/num;
			System.out.println(i);
			return "success";
		}
@ControllerAdvice
public class ExceptionHandler {
	@org.springframework.web.bind.annotation.ExceptionHandler(ArithmeticException.class)
	public ModelAndView handlerException(Exception ex){
		System.out.println("--->>"+ex);
		ModelAndView modelAndView=new ModelAndView("error");
		modelAndView.addObject("exception",ex);
		return modelAndView;
	}
}

 

                  17、SpringMVC在restfull風格中無法獲取小數點,詳細原因參考

         解決方法有兩種:

             1.在佔位符裡新增:.+,

             2.在<mvc:annotation-driven></mvc:annotation-driven>中新增<mvc:path-matching registered-suffixes-only="true"/>

.三、總結 

      1、SpringMVC執行流程。

        一、先用文字描述

        1.使用者傳送請求到DispatchServlet

        2.DispatchServlet根據請求路徑查詢具體的Handler

        3.HandlerMapping返回一個HandlerExcutionChain給DispatchServlet

         HandlerExcutionChain:Handler和Interceptor集合

        4.DispatchServlet呼叫HandlerAdapter介面卡

        5.HandlerAdapter呼叫具體的Handler處理業務

        6.Handler處理結束返回一個具體的ModelAndView給介面卡

           ModelAndView:model-->資料模型,view-->檢視名稱

        7.介面卡將ModelAndView給DispatchServlet

        8.DispatchServlet把檢視名稱給ViewResolver檢視解析器

        9.ViewResolver返回一個具體的檢視給DispatchServlet

        10.填充資料,渲染檢視。

        11.展示給使用者

       二、畫圖解析

 

         2 、SpringMVC三大元件處理器對映器、處理器介面卡、檢視解析器。

處理器對映器:註解式處理器對映器,對類中標記了@ResquestMapping的方法進行對映,根據@ResquestMapping定義的url匹配@ResquestMapping標記的方法,匹配成功返回HandlerMethod物件給前端控制器。

<!-- 配置處理器對映器 -->

<bean

class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />

處理器介面卡:對標記@ResquestMapping的方法進行適配

<!-- 配置處理器介面卡 -->

<bean

class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />

解決辦法:

SpringMVC使用<mvc:annotation-driven>自動載入RequestMappingHandlerMapping和RequestMappingHandlerAdapter

可以在springmvc.xml配置檔案中使用<mvc:annotation-driven>替代註解處理器和介面卡的配置。

<!-- 註解驅動 -->

<mvc:annotation-driven />

 

檢視解析器:檢視解析器使用SpringMVC框架預設的InternalResourceViewResolver,這個檢視解析器支援JSP檢視解析。

<!-- 配置檢視解析器 -->

<bean

class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<!-- 配置邏輯檢視的字首 -->

<property name="prefix" value="/WEB-INF/jsp/" />

<!-- 配置邏輯檢視的字尾 -->

<property name="suffix" value=".jsp" />

</bean>

最終jsp實體地址:字首+邏輯檢視名+字尾


     3、引數型別推薦使用包裝資料型別,因為基礎資料型別不可以為null。

 

    4、SpringMVC與struts2的不同

  1. SpringMVC的入口是一個servlet即前端控制器,而struts2入口是一個filter過濾器。
  2. SpringMVC是基於方法開發(一個url對應一個方法),請求引數傳遞到方法的形參,可以設計為單例或多例(建議單例),struts2是基於類開發,傳遞引數是通過類的屬性,只能設計為多例。
  3. Struts2採用值棧儲存請求和響應的資料,通過OGNL存取資料, SpringMVC通過引數解析器是將request請求內容解析,並給方法形參賦值,將資料和檢視封裝成ModelAndView物件,最後又將ModelAndView中的模型資料通過request域傳輸到頁面。Jsp檢視解析器預設使用jstl。