springmvc知識點整理

1.Springmvc架構
html

2.Springmvc組件
三大組件:處理器映射器,處理器適配器,視圖解析器
處理器映射器:註解式處理器映射器,對類中標記了@ResquestMapping的方法進行映射,根據@ResquestMapping定義的url匹配@ResquestMapping標記的方法,匹配成功返回HandlerMethod對象給前端控制器。
<!-- 配置處理器映射器 -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />前端

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

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

解決辦法:
SpringMVC使用<mvc:annotation-driven>自動加載RequestMappingHandlerMapping和RequestMappingHandlerAdapter
能夠在springmvc.xml配置文件中使用<mvc:annotation-driven>替代註解處理器和適配器的配置。
<!-- 註解驅動 -->
<mvc:annotation-driven />spring


視圖解析器:視圖解析器使用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
整形:Integer、int
字符串:String
單精度:Float、float
雙精度:Double、double
布爾型:Boolean、boolean
說明:對於布爾類型的參數,請求的參數值爲true或false。或者1或0
請求url:
http://localhost:8080/xxx.action?id=2&status=false
處理器方法:
public String editItem(Model model,Integer id,Boolean status)json

3.1簡單參數的綁定(@RequestParam)
當請求的參數名稱和處理器形參名稱一致時會將請求參數與形參進行綁定,若不一致,就須要@RequestParam數組

value:參數名字,即入參的請求參數名字,如value=「itemId」表示請求的參數 區中的名字爲itemId的參數的值將傳入
required:是否必須,默認是true,表示請求中必定要有相應的參數,不然將報錯
TTP Status 400 - Required Integer parameter 'XXXX' is not present
defaultValue:默認值,表示若是請求中沒有同名參數時的默認值
public String queryItemById(@RequestParam(value = "itemId", required = true, defaultValue = "1") Integer id,ModelMap modelMap) {}瀏覽器

這裏須要傳入的是id,實際傳入的是itemId,須要用@RequestParam轉換一下tomcat

3.2pojo參數綁定
若是提交的參數不少,或者提交的表單中的內容不少的時候,可使用簡單類型接受數據,也可使用pojo接收數據,可是pojo對象中的屬性名和表單中input的name屬性一致。


3.3自定義參數綁定
因爲日期數據有不少種格式,springmvc沒辦法把字符串轉換成日期類型。因此須要自定義參數綁定
通常使用<mvc:annotation-driven/>註解驅動加載處理器適配器,能夠在此標籤上進行配置
//Converter<S, T>
//S:source,須要轉換的源的類型
//T:target,須要轉換的目標類型
public class DateConverter implements Converter<String, Date> {

@Override
public Date convert(String source) {
try {
// 把字符串轉換爲日期類型
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse(source);

return date;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 若是轉換異常則返回空
return null;
}
}


<!-- 配置註解驅動 -->
<!-- 若是配置此標籤,能夠不用配置... -->
<mvc:annotation-driven conversion-service="conversionService" />

<!-- 轉換器配置 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cn.itcast.springmvc.converter.DateConverter" />
</set>
</property>
</bean>

3.3高級參數綁定
3.3.1綁定數組

 

3.3.2將數據綁定到list集合
將pojo放入list集合中,注意:接收List類型的數據必須是pojo的屬性,若是方法的形參爲ArrayList類型沒法正確接收到數據

4.RequestMapping
4.1url路徑映射
@RequestMapping(value="item")或@RequestMapping("/item"),value的值是數組,能夠將多個url映射到同一個方法

4.2請求方法的限定
 限定GET方法
@RequestMapping(method = RequestMethod.GET)

若是經過POST訪問則報錯:
HTTP Status 405 - Request method 'POST' not supported

例如:
@RequestMapping(value = "itemList",method = RequestMethod.POST)

 限定POST方法
@RequestMapping(method = RequestMethod.POST)

若是經過GET訪問則報錯:
HTTP Status 405 - Request method 'GET' not supported

 GET和POST均可以
@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST})

5.Controller返回值

5.1Redirect重定向
Contrller方法返回字符串能夠重定向到一個url地址

// 重定向後瀏覽器地址欄變動爲重定向的地址,
// 重定向至關於執行了新的request和response,因此以前的請求參數都會丟失
// 若是要指定請求參數,須要在重定向的url後面添加 ?itemId=1 這樣的請求參數
return "redirect:/itemEdit.action?itemId=" + item.getId();

5.2Forward轉發
Controller方法執行後繼續執行另外一個Controller方法
// 修改商品成功後,繼續執行另外一個方法
// 使用轉發的方式實現。轉發後瀏覽器地址欄仍是原來的請求地址,
// 轉發並無執行新的request和response,因此以前的請求參數都存在
return "forward:/itemEdit.action";

6.異常處理器
springmvc在處理請求過程當中出現異常信息交由異常處理器進行處理,自定義異常處理器能夠實現一個系統的異常處理邏輯。
系統的dao、service、controller出現都經過throws Exception向上拋出,最後由springmvc前端控制器交由異常處理器進行異常處理
6.1自定義異常類
爲了區別不一樣的異常,一般根據異常類型進行區分,這裏咱們建立一個自定義系統異常。
若是controller、service、dao拋出此類異常說明是系統預期處理的異常信息。
public class MyException extends Exception {
// 異常信息
private String message;

public MyException() {
super();
}

public MyException(String message) {
super();
this.message = message;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

}

6.2自定義異常處理器
public class CustomHandleException implements HandlerExceptionResolver {

@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception exception) {
// 定義異常信息
String msg;

// 判斷異常類型
if (exception instanceof MyException) {
// 若是是自定義異常,讀取異常信息
msg = exception.getMessage();
} else {
// 若是是運行時異常,則取錯誤堆棧,從堆棧中獲取異常信息
Writer out = new StringWriter();
PrintWriter s = new PrintWriter(out);
exception.printStackTrace(s);
msg = out.toString();

}

// 把錯誤信息發給相關人員,郵件,短信等方式

// 返回錯誤頁面,給用戶友好頁面顯示錯誤信息
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg", msg);
modelAndView.setViewName("error");

return modelAndView;
}
}

在springmvc.xml中添加:
<!-- 配置全局異常處理器 -->
<bean
id="customHandleException" class="cn.itcast.ssm.exception.CustomHandleException"/>

7.上傳圖片
7.1配置虛擬路徑
在tomcat上配置圖片虛擬目錄,在tomcat下conf/server.xml中添加:
<Context docBase="D:\develop\upload\temp" path="/pic" reloadable="false"/>
訪問http://localhost:8080/pic便可訪問D:\develop\upload\temp下的圖片。
也能夠經過eclipse配置,以下圖:


複製一張圖片到存放圖片的文件夾,使用瀏覽器訪問
測試效果,以下圖:

7.2jar包以及視圖解析器

在springmvc.xml中配置文件上傳解析器
<!-- 文件上傳,id必須設置爲multipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 設置文件上傳大小 -->
<property name="maxUploadSize" value="5000000" />
</bean>

7.3圖片上傳代碼示例
@RequestMapping("updateItem")
public String updateItemById(Item item, MultipartFile pictureFile) throws Exception {
// 圖片上傳
// 設置圖片名稱,不能重複,可使用uuid
String picName = UUID.randomUUID().toString();

// 獲取文件名
String oriName = pictureFile.getOriginalFilename();
// 獲取圖片後綴
String extName = oriName.substring(oriName.lastIndexOf("."));

// 開始上傳
pictureFile.transferTo(new File("C:/upload/image/" + picName + extName));

// 設置圖片名到商品中
item.setPic(picName + extName);
// ---------------------------------------------
// 更新商品
this.itemService.updateItemById(item);

return "forward:/itemEdit.action";
}

8.Json數據交互
8.1@RequestBody
@RequestBody註解用於讀取http請求的內容(字符串),經過springmvc提供的HttpMessageConverter接口將讀到的內容(json數據)轉換爲java對象並綁定到Controller方法的參數上。
@RequestBody註解實現接收http請求的json數據,將json數據轉換爲java對象進行綁定

8.2@ResponseBody
@ResponseBody註解用於將Controller的方法返回的對象,經過springmvc提供的HttpMessageConverter接口轉換爲指定格式的數據如:json,xml等,經過Response響應給客戶端
@ResponseBody註解實現將Controller方法返回java對象轉換爲json響應給客戶端。

8.3Json請求,Json響應(jackson)
若是須要springMVC支持json,必須加入json的處理jar

8.4Json轉換器
若是不使用註解驅動<mvc:annotation-driven />,就須要給處理器適配器配置json轉換器

在springmvc.xml配置文件中,給處理器適配器加入json轉換器:
<!--處理器適配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
</list>
</property>
</bean>

9.RESTful支持
9.1資源操做
傳統方式操做資源
http://127.0.0.1/item/queryItem.action?id=1 查詢,GET
http://127.0.0.1/item/saveItem.action 新增,POST
http://127.0.0.1/item/updateItem.action 更新,POST
http://127.0.0.1/item/deleteItem.action?id=1 刪除,GET或POST

使用RESTful操做資源
http://127.0.0.1/item/1 查詢,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 刪除,DELETE

9.2從url上獲取參數(@PathVariable)
@RequestMapping("item/{id}")
@ResponseBody
public Item queryItemById(@PathVariable() Integer id) {}

{xxx}叫作佔位符,請求的URL能夠是「item /1」或「item/2」
使用(@PathVariable() Integer id)獲取url上的數據

若是@RequestMapping中表示爲"item/{id}",id和形參名稱一致,@PathVariable不用指定名稱。若是不一致,例如"item/{ItemId}"則須要指定名稱@PathVariable("itemId")

注意兩個區別
1. @PathVariable是獲取url路徑上數據的。@RequestParam獲取靜態的url請求參數的(包括post表單提交)
1. @Controller
2. @RequestMapping("/owners/{ownerId}")
3. public class RelativePathUriTemplateController {
4.
5. @RequestMapping("/pets/{petId}")
6. public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
7. // implementation omitted
8. }
9. }
上面代碼把URI template 中變量 ownerId的值和petId的值,綁定到方法的參數上。若方法參數名稱和須要綁定的uri template中變量名稱不一致,須要在@PathVariable("name")指定uri template中的名稱

2. 若是加上@ResponseBody註解,就不會走視圖解析器,不會返回頁面,目前返回的json數據。若是不加,就走視圖解析器,返回頁面

 

9.3最佳實踐
9.3.1響應設計


錯誤2點:
第一違反了僅僅用來傳輸數據的原則,status:200不是響應狀態碼,通常稱之爲業務狀態碼。
第二違反了拿來就用的原則,數據被包裝了2層

9.3.2指定響應屬性字段

如介紹,按需提取,須要什麼就提取什麼,而不是所有提取。例如:根據id查詢用戶信息,可能我就須要用戶名稱就行,可是結果卻返回跟用戶相關的全部信息,
包括年齡,性別等。。。。,這都不是我想要的數據,我僅僅須要姓名而已。
9.3.3http的響應狀態碼

9.4操做資源時注意更新和刪除
9.4.1更新操做
默認狀況下,PUT請求是沒法提交表單數據的,須要在web.xml中添加過濾器解決:

<!-- 解決PUT請求沒法提交表單數據的問題 -->
<filter>
<filter-name>HttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

 

9.4.2刪除操做
須要在web.xml中添加過濾器解決DELETE請求沒法提交表單數據的問題:
<!--
將POST請求轉化爲DELETE或者是PUT
要用_method指定真正的請求參數
-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


10.攔截器
10.1自定義攔截器類
public class HandlerInterceptor1 implements HandlerInterceptor {
// controller執行後且視圖返回後調用此方法
// 這裏可獲得執行controller時的異常信息
// 這裏可記錄操做日誌
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("HandlerInterceptor1....afterCompletion");
}

// controller執行後但未返回視圖前調用此方法
// 這裏可在返回用戶前對模型數據進行加工處理,好比這裏加入公用信息以便頁面顯示
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("HandlerInterceptor1....postHandle");
}

// Controller執行前調用此方法
// 返回true表示繼續執行,返回false停止執行
// 這裏能夠加入登陸校驗、權限攔截等
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("HandlerInterceptor1....preHandle");
// 設置爲true,測試使用
return true;
}
}
10.2攔截器配置

在springmvc.xml中配置攔截器
<!-- 配置攔截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 全部的請求都進入攔截器 -->
<mvc:mapping path="/**" />
<!-- 配置具體的攔截器 -->
<bean class="cn.itcast.ssm.interceptor.HandlerInterceptor1" />
</mvc:interceptor>
<mvc:interceptor>
<!-- 全部的請求都進入攔截器 -->
<mvc:mapping path="/**" />
<!-- 配置具體的攔截器 -->
<bean class="cn.itcast.ssm.interceptor.HandlerInterceptor2" />
</mvc:interceptor>
</mvc:interceptors>

總結:
preHandle按攔截器定義順序調用
postHandler按攔截器定義逆序調用
afterCompletion按攔截器定義逆序調用

postHandler在攔截器鏈內全部攔截器返成功調用
afterCompletion只有preHandle返回true才調用
10.3攔截器應用案例
判斷用戶是否登陸

Jsp頁面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<form action="${pageContext.request.contextPath }/user/login.action">
<label>用戶名:</label>
<br>
<input type="text" name="username">
<br>
<label>密碼:</label>
<br>
<input type="password" name="password">
<br>
<input type="submit">

</form>

</body>
</html>

登陸的controller
@Controller
@RequestMapping("user")
public class UserController {

/**
* 跳轉到登陸頁面
*
* @return
*/
@RequestMapping("toLogin")
public String toLogin() {
return "login";
}

/**
* 用戶登陸
*
* @param username
* @param password
* @param session
* @return
*/
@RequestMapping("login")
public String login(String username, String password, HttpSession session) {
// 校驗用戶登陸
System.out.println(username);
System.out.println(password);

// 把用戶名放到session中
session.setAttribute("username", username);

return "redirect:/item/itemList.action";
}

}

攔截器的編寫
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
// 從request中獲取session
HttpSession session = request.getSession();
// 從session中獲取username
Object username = session.getAttribute("username");
// 判斷username是否爲null
if (username != null) {
// 若是不爲空則放行
return true;
} else {
// 若是爲空則跳轉到登陸頁面
response.sendRedirect(request.getContextPath() + "/user/toLogin.action");
}

return false;
}

在springmvc.xml配置攔截器
<mvc:interceptor>
<!-- 配置商品被攔截器攔截 -->
<mvc:mapping path="/item/**" />
<!-- 配置具體的攔截器 -->
<bean class="cn.itcast.ssm.interceptor.LoginHandlerInterceptor" />
</mvc:interceptor>

 

11.springmvc與struts2不一樣
一、 springmvc的入口是一個servlet即前端控制器,而struts2入口是一個filter過濾器。
二、 springmvc是基於方法開發(一個url對應一個方法),請求參數傳遞到方法的形參,能夠設計爲單例或多例(建議單例),struts2是基於類開發,傳遞參數是經過類的屬性,只能設計爲多例。
三、 Struts採用值棧存儲請求和響應的數據,經過OGNL存取數據, springmvc經過參數解析器是將request請求內容解析,並給方法形參賦值,將數據和視圖封裝成ModelAndView對象,最後又將ModelAndView中的模型數據經過request域傳輸到頁面。Jsp視圖解析器默認使用jstl。

12.springmvc和mybatis整合
須要的jar包:
1. spring(包括springmvc)
2. mybatis
3. mybatis-spring整合包
4. 數據庫驅動
第三方鏈接池。

Dao層:
一、SqlMapConfig.xml,空文件便可,可是須要文件頭。
二、applicationContext-dao.xml
a) 數據庫鏈接池
b) SqlSessionFactory對象,須要spring和mybatis整合包下的。
c) 配置mapper文件掃描器。

Service層:
一、applicationContext-service.xml包掃描器,掃描@service註解的類。
二、applicationContext-trans.xml配置事務。

Controller層:
一、Springmvc.xml
a) 包掃描器,掃描@Controller註解的類。
b) 配置註解驅動
c) 配置視圖解析器

Web.xml文件:一、配置spring配置前端控制器

相關文章
相關標籤/搜索