SpringMVC學習筆記(未完)
阿新 • • 發佈:2018-11-07
前邊的入門就不說了~~
如果有不懂的可以參考SpringMVC 4.2.4.RELEASE官方中文API (進入下載頁直接下載)
1、矩陣變數
2、媒體型別3、請求引數和請求頭(params="myParam=myValue")
4、REST架構
(1)、HTTP協議4個操作動詞(對應4中基本操作):
GET(獲取資源)、
POST(新建資源)、
PUT(更新資源)、
DELETE(刪除資源)
HiddenHttpMethodFilter
(2)REST架構風格:
理解本真的REST架構風格--http://kb.cnblogs.com/page/186516
深入淺出REST--http://www.infoq.com/cn/articles/rest-introduction
5、@SessionAttribute:將資料放到Session域中,該註解只能放到類上面
*注意:在@ModelAttribute 標記的方法中,放到Map時的鍵需要和目標方法入參型別的第一個字母小寫的字串一致
eg.
@ModelAttribute
public void getUser(@RequestParam(value="id") Integer id,Map<String,Object> map){
//從資料庫中取出物件
User user=new User();
System.out.println("從資料庫中獲取一個物件:"+user);
map.put("user",user);
}
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user){
System.out.println("修改後:"+user);
return "success";
}
以上程式碼執行流程:
1、執行@ModelAttribute 註解修飾的方法:從資料庫中取出物件,把物件放入到Map中,鍵為:user
2、SpringMVC 從Map中去除User物件,並把表單的請求引數賦給該User物件的對應屬性,
3、SpringMVC 把上述物件傳入目標方法(testModelAttribute)的引數。
1.呼叫@ModelAttribute 註解修飾的方法,實際上吧@ModelAttribute 方法中的Map中的資料放在了implicitModel中
2、解析請求處理器的目標引數,實際上該目標引數來自於WebDataBinder物件的target屬性
1)、建立WebDataBinder物件
1、確定ObjectName屬性:若傳入attrName屬性值為"",則objectName為類,類名第一個首字母小寫,
*注意:attrName.若目標方法的POJO屬性使用了@ModelAttribute來修飾,則attrName值即為@ModelAttribute的value屬性值
2、確定target屬性
>在implicizModel中查詢attrName對應的屬性值,若存在,OK
>若不存在,則驗證當前Handler是否使用了@SessionAttribute進行修飾,若使用了,則嘗試Session中獲取attrName所對應的屬性值.若session中沒有對應的屬性值,則丟擲了異常。
>若Handler沒有使用@SessionAttributes 進行修飾,或@SessionAttributes 沒有使用value值指定的Key和attrName相匹配,則通過反射建立了POJO物件。
2)、SpringMVC把表單的請求引數賦給了 WebDataBinder 的target對應的屬性,
3)、SpringMVC會把WebDataBinder 的 attrName 的target給到impliciModel,近而傳到request域物件中。
4)、把WebDataBinder的target作為引數傳遞給目標方法的入參。
1、確定一個Key
1)、若目標方法的POJO型別的引數沒有使用@ModelAttribute 作為修飾,則key為POJO類名第一個字母小寫,
2)、若使用了@ModelAttribute 來修飾,則key為@ModelAttribute 註解value的值。
2、在implicitModel中查詢key對應的物件,若存在,則作為入參傳入。
1)、若在@ModelAttribute 標記的方法中在Map中儲存過,且key和1確定的key一致,則會獲取到。
3、若implicitModel中不存在key對應的物件,則檢查當前的Handler是否使用了@SessionAttributes 註解修飾,若使用該註解,且@SessionAttributes 註解的value屬性值中包含了key,則會從HttpSession中獲取key所對應的value值,若存在則直接傳入到目標方法的入參中,若不存在將丟擲異常。
4、若Handler沒有標識@SessionAttributes 註解或@SessionAttributes註解的value 值中不包含key則會通過反射來建立POJO型別的引數,傳入為目標方法的引數。
5、SpringMVC會把 key 和 POJO 型別的物件儲存到implicitModel中,進而會儲存到request中,
1、在Spring-servlet.xml中配置檢視解析器,
<!--配置 BeanNameViewResolver 檢視解析器:使用檢視的名字來解析檢視-->
<!-- 通過order屬性來定義檢視解析器的優先順序,order值越小優先順序越高-->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="100"></property>
</bean>
8、 SpringMVC的<from:form>
1、使用SpringMVC的<from:form>標籤時,在域物件中必須有一個與表單欄位對應的bean,可以通過form的modelAttribute屬性定義繫結的bean,若不設定預設為command,
eg.
在Controller中:
@RequestMapping(value="user", method=RequestMethod.GET)
public String (Map<Strign,Object> map){
map.put("user",new User()); //將user放到域物件中,
return "user_add";
}
user_add.jsp:
<form:form action="user" method="POST" modelAttribute="user">
.....
//欄位
//欄位
</form:form>
9、SpringMVC處理靜態資源
1、問題出現:
一般REST風格的URL不會帶.do或.html字尾,若將DispacherServlet請求對映配置為/,則SpringMVC會捕獲WEB容器的所有請求,所以當我 們試圖使用外部的js、css、images等靜態資源時,SpringMVC 會將他們當成一個普通的請求處理,導致找不到對應的處理器而丟擲異常。
2、解決方法:
在SpringMVC的配置檔案中配置<mvc:default-servlet-handler/>,會在SpringMVC上下文中定義一個DefaultServletHttpRequestHandler, 他會對 DispatcherServlet 的請求進行篩選,如果是沒有經過對映的請求,就將該請求交給Web伺服器預設的Servlet處理,如果不是靜態資源的 請求,才由DispatcherServlet繼續處理。一般WEB應用伺服器預設的Servlet名稱都是default,若使用的Servlet名稱不是default,則可以在default- servlet-handler中顯示定義。
10、自定義型別轉換器
在springmvc-servlet.xml中配置:
<!--配置 ConversionService -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="自定義型別轉換器類名第一個字母小寫"/>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
11、資料格式化
@NumberFormat 數字格式轉換器
@DateFormat 日期格式轉換器
如果轉換出錯,可以用BindingResult類檢視
12、資料校驗
1、使用JSR 303驗證標準
2、加入hibernate validator 的支援(jar包或dependency)
3、在springmvc-servlet.xml在中新增<mvc:annotation-driven/>
4、在bean的屬性上新增相應的註解
5、在目標方法bean型別的前面新增@valid註解
如果填寫資料不符合要求,會出現如下警告
13、處理Json
1、加入jar包或Maven依賴
2、編寫目標方法,使其返回Json對應的物件或集合
3、在目標方法上新增@RequestBody註解
14、異常處理
1、在@ExceptionHandler 標記方法的入參中可以加入Exception型別的引數,該引數即對應發生的異常物件
2、@ExceptionHandler 方法的入參中不能傳入 Map. 若希望把異常資訊傳導頁面上, 需要使用 ModelAndView 作為返回值
eg.
@ExceptionHandler({ArithmeticException.class})
public ModelAndView handleArithmeticException(Exception ex){
System.out.println("出異常了: " + ex);
ModelAndView mv = new ModelAndView("error");
mv.addObject("exception", ex);
return mv;
}
3、 @ExceptionHandler 方法標記的異常有優先順序的問題.
4、@ControllerAdvice: 如果在當前 Handler 中找不到 @ExceptionHandler 方法來出來當前方法出現的異常, 則將去
@ControllerAdvice 標記的類中查詢 @ExceptionHandler 標記的方法來處理異常.
5、使用 SimpleMappingExceptionResolver
eg.
<!-- 配置使用 SimpleMappingExceptionResolver 來對映異常 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- exceptionAttribute 屬性預設值為 "exception",在頁面上可以通過${ex}直接獲取異常資訊-->
<property name="exceptionAttribute" value="ex"></property>
<property name="exceptionMappings">
<props>
<prop key="java.lang.ArrayIndexOutOfBoundsException">error</prop>
</props>
</property>
</bean>