springmvc知識點整理


1.Springmvc架構

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
整形: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)

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轉換一下

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不同
1、 springmvc的入口是一個servlet即前端控制器,而struts2入口是一個filter過濾器。
2、 springmvc是基於方法開發(一個url對應一個方法),請求參數傳遞到方法的形參,可以設計為單例或多例(建議單例),struts2是基於類開發,傳遞參數是通過類的屬性,只能設計為多例。
3、 Struts采用值棧存儲請求和響應的數據,通過OGNL存取數據, springmvc通過參數解析器是將request請求內容解析,並給方法形參賦值,將數據和視圖封裝成ModelAndView對象,最后又將ModelAndView中的模型數據通過request域傳輸到頁面。Jsp視圖解析器默認使用jstl。

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

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

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

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

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM