Springmvc
- 回顧
- 理解MVC設計模式
- 視圖(View)-對應組件:JSP或者HTML文件
- 控制器(Controller)-對應組件:Servlet
- 模型(Model) -對應組件:JavaBean
- MVC 優點
- 多視圖共享一個模型,大大提高代碼的可重用性
- MVC三個模塊相互獨立,鬆耦合架構
- 控制器提高了應用程序的靈活性和可配置性
- 有利於軟件工程化管理
- 完美的系統架構 = 鬆耦合+高重用性+高擴展性
- 理解MVC設計模式
- Spring MVC框架搭建步驟
- 下載jar文件並導入工程
- spring-web-3.2.13.RELEASE.jar
- spring-webmvc-3.2.13.RELEASE.jar
- 配置文件
- 在web.xml中配置Servlet
- 創建Spring MVC的配置文件
- 創建Controller-處理請求的控制器
- BeanNameUrlHandlerMapping
- 創建View-jsp
- 部署運行
- 下載jar文件並導入工程
- Web.xml
-
web.xml <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping>
-
- Springmvc.xml
-
<bean name="/index.action" class="com.company.controller.IndexController"></bean> <!-- 對轉向頁面的路徑解析。prefix:前綴, suffix:後綴 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"></property> </bean>
-
- 創建Controller
-
IndexController public class IndexController extends AbstractController { @Override protected ModelAndView handleRequestInternal(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception { System.out.println("hello, SpringMVC"); return new ModelAndView("index"); } }
-
- 註解驅動控制器
- 基於註解的處理器
-
<context:component-scan />
-
-
@Controller
- 標註一個普通的JavaBean成爲可以處理請求的控制器
- @RequestMapping
- 通過請求URL進行映射
- 配置MVC註解驅動
-
<mvc:annotation-driven /><!-- 配置註解驅動 -->
- 自動註冊DefaultAnootationHandlerMapping,AnotationMethodHandlerAdapter
- 提供一些列:數據綁定,數字和日期的format @NumberFormat, @DateTimeFormat, xml,json默認讀寫支持
-
- 基於註解的處理器
-
SpringMVC請求的流程
- Spring MVC體系結構
- DispatcherServlet(前端控制器)
- web.xml中配置
- Spring MVC最核心的類
- Handler(處理器):對應MVC中C(Controller)
- 標註了@RequestMapping的所有方法都可以看作是一個Handler
- 作用:實際處理請求
- 類型:Object
- ModelAndView(視圖解析器)
- 邏輯視圖名
- 模型對象
- DispatcherServlet(前端控制器)
- 核心組件
- HandlerMapping(處理器映射)
- BeanNameUrlHandlerMapping(默認)
- 將請求URL映射到同名的控制器Bean上
- DefaultAnnotationHandlerMapping
- 將請求映射到標註@RequestMapping註解的控制器和處理方法上
- RequestMappingHandlerMapping
- BeanNameUrlHandlerMapping(默認)
- HandlerAdapter(適配器)
- RequestMappingHandlerAdapter
- AnnotationMethodHandlerAdapter
- ViewResolver(視圖解析器)
- InternalResourceView
- HandlerMapping(處理器映射)
- Springmvc框架特點
- 清晰地角色劃分
- 靈活的配置功能
- 提供了大量的控制器接口和實現類
- 真正做到了View層的實現無關(JSP,VUE,angularjs)
- 國際化支持
- 面向接口編程
- Spring提供了web應用開發的一整套流程,不僅僅MVC,他們之間可以很方便的結合一起
- SpringMVC參數傳遞,轉發跳轉
- 處理器映射
- 方式1
-
@RequestMapping("/welcome") public String index(String username){ return "index"; }
-
- 方式2
-
@RequestMapping("/welcome") public String index(@RequestParam String username){ return "index"; }
-
- 方式3
-
@RequestMapping("/welcome") public String index(@RequestParam(value="username",required=false) String username) { return "index"; }
-
- 方式1
- @RequestParam
- value:參數名稱
- defaultValue:默認值
- required:是否必須
- @RequestMapping
- 標註在類定義處
- 標註在方法定義處
- 映射規則
- 通過請求URL進行映射
- 通過請求參數進行映射
- 若選擇方法參數直接入參的話,方法入參名必須與請求中參數名保持一致
- 通過請求方法進行映射
- GET
- POST
-
@RequestMapping(value="/welcome", method=RequestMethod.GET,params="username")
- 處理器映射
-
如何將模型數據傳遞給視圖?
- ModelAndView
- 包含視圖信息和模型數據信息
- 常用方法
- 添加模型數據
- ModelAndView addObject(String attributeName,Object attributeValue);
- ModelAndView addAllObjects(Map<String,?> modelMap);
- 設置視圖
- void setView(View view);
- void setViewName(String viewName);
- 添加模型數據
-
12.如何將模型數據傳遞給視圖? (1)ModelAndView ①包含視圖信息和模型數據信息 ②常用方法 1)添加模型數據 a.ModelAndView addObject(String attributeName,Object attributeValue); b.ModelAndView addAllObjects(Map<String,?> modelMap); 2)設置視圖 a.void setView(View view); b.void setViewName(String viewName);
-
Model
- 數據結構:Map類型
- 常用方法:添加模型數據
-
Model.addAttribute(String attributeName,Object attributeValue);
-
@RequestMapping("/index2") public String index2(String username,Model model){ logger.info("welcome username : " + username); model.addAttribute(username); User user = new User(); user.setUserName(username); model.addAttribute(user); return "index"; }
- Model其實就是一個Map的數據結構,那麼是否可以使用Map作爲處理方法入參?
- ModelAndView
- InternalResourceViewResolver
- prefix
- suffix
-
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
- Spring的常用標籤
- @ModelAttribute
- 不僅僅和從頁面中獲取對象的所有屬性,而且可以將對象放入request當中
- @DateTimeFormat(pattern="yyyy-MM-dd")的使用
- 設置對應日期屬性的字符串格式
-
/** * @ModelAttribute 不僅僅和從頁面中獲取對象所有屬性, * 而且可以將對象放入request當中 * @param user * @return * @ModelAttribute 的使用 * @DateTimeFormat(pattern="yyyy-MM-dd")的使用 */ @RequestMapping("/add") public String add(@ModelAttribute("user") User user){ System.out.println(user.getUserName()); System.out.println(user.getPassWord()); System.out.println(user.getBirthday()); return "showuser"; }
- @ModelAttribute
- @ModelAttribute
- 不僅僅和從頁面中獲取對象的所有屬性,而且可以將對象放入request當中
- @DateTimeFormat(pattern="yyyy-MM-dd")的使用
- 設置對應日期屬性的字符串格式
- Struts2和Springmvc的對比
- Struts2 中 result
- 字符串 一個對應一個 View視圖
- springmvc 對於跳轉這件事,簡化!(不用配置,可以使用字符串自動跳轉)
- 但是如果路徑特別深,需要 "視圖解析器",在spring-servlet.xml中配置
- 除去了前綴,後綴,使用ModelAndView,將視圖頁面和對象放到ModelAndView對象當中,實現跳轉功能
- Struts2底層實現是過濾器,Springmvc底層是servlet
- 頁面跳轉的多種方式
- 使用字符串:forward:/頁面全名稱
-
轉發到對應的頁面: return "forward:/welcome.jsp";
-
-
使用視圖解析器
-
路徑特別深,需要 "視圖解析器",在spring-servlet.xml中配置 return "admin/wel"; 相當於: return "forward:/WEB-INF/jsp/admin/wel.jsp";
-
- 重定向到指定路徑,可以是互聯網上的任意地址:redirect:網址
-
return "redirect:http://www.baidu.com";
-
- 使用ModelAndView設置跳轉位置
-
ModelAndView mv = new ModelAndView(); mv.setViewName("admin/wel"); return mv;
-
- 使用字符串:forward:/頁面全名稱
- 使用REST風格
- REST即表述性狀態傳遞(英文:Representational State Transfer,簡稱REST)是Roy Fielding博士在2000年他的博士論文中提出來的一種軟件架構風格。它是一種針對網絡應用的設計和開發方式,可以降低開發的複雜性,提高系統的可伸縮性。
-
@RequestMapping(value="/view/{id}", method=RequestMethod.GET) public String view(@PathVariable String id,Model model){ //......中間代碼省略 }
-
- REST即表述性狀態傳遞(英文:Representational State Transfer,簡稱REST)是Roy Fielding博士在2000年他的博士論文中提出來的一種軟件架構風格。它是一種針對網絡應用的設計和開發方式,可以降低開發的複雜性,提高系統的可伸縮性。
- pringmvc文件上傳
- MultipartResolver接口
- ①用於處理上傳請求,將上傳請求包裝成可以直接獲取文件的數據,方便操作
- 兩個實現類
- StandardServletMultipartResolver
- 使用了Servlet3.0標準的上傳方式
- CommonsMultipartResolver
- 使用了Apache的commons-fileupload來完成具體的上傳操作
- StandardServletMultipartResolver
- MultipartResolver接口
- 文件上傳的實現步驟
- 導入jar文件
- commons-io-2.4.jar
- commons-fileupload-1.2.2.jar
- 配置MultipartResolver(springmvc-servlet.xml)
- 使用CommonsMultipartResolver配置一個MultipartResolver解析器
-
<bean id="multipartResolver" class="org.springframework.web.multipart.commons. CommonsMultipartResolver"> <property name="maxUploadSize" value="5000000"/> <property name="defaultEncoding" value="UTF-8"/> </bean>
-
<!-- 處理文件上傳 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="gbk" /> <!-- 默認編碼 (ISO-8859-1) --> <property name="maxInMemorySize" value="10240" /> <!-- 最大內存大小 (10240) --> <property name="uploadTempDir" value="/upload/" /> <!-- 上傳後的目錄名 --> <property name="maxUploadSize" value="-1" /> <!-- 最大文件大小,-1爲無限止(-1) --> </bean>
- 編寫文件上傳表單頁
- method="POST" enctype="multipart/form-data" 指定表單內容類型,支持文件上傳
- <input type="file" name="file"/> 用來上傳文件的file組件
-
<form action="upload.action" method="post" enctype="multipart/form-data"> 姓名:<input type="text" name="name" /> 頭像:<input type="file" name="file" /> <input type="submit" /> </form>
- 導入jar文件
-
文件上傳中的業務流程
- 使用上傳類,方法
- MultipartFile
- Spring MVC會將上傳文件綁定到MultipartFile對象中,並通過該對象完成文件的上傳操作
- 提供的方法
- CommonsMultipartFile類實現:MultipartFile接口
- MultipartFile
- 文件上傳中需要注意的細節
- File.separator
- Windows、Linux自適應路徑分隔符
- 低入侵性的代碼實現
- 必須對上傳文件進行重命名
- 原因
- 原文件名存在中文 亂碼問題
- 原文件名與服務器上已有文件重名 覆蓋問題
- 重新定義上傳文件名(保證不重名)
- 當前系統時間+隨機數+“_Personal.jpg”
- 原因
- 上傳位置:
- 指定磁盤路徑
- 文件上傳成功後
- 獲取文件上傳 文件的url訪問地址
- 頁面展示該文件,並可以對該文件進行下載。
- File.separator
- Springmvc處理AJAX請求
- 相關jar包:
- jackson-all-1.8.10.jar
- fastjson-1.2.47.jar(阿里巴巴)
- 以上兩個jar包都可以處理AJAX請求
- 相關jar包:
- 在控制器中增加方法
- 使用註解:@ResponseBody
- 該註解設置返回值爲JSON類型
- @ResponseBody註解的作用是將controller的方法返回的對象通過適當的轉換器轉換爲指定的格式之後,寫入到response對象的body區,通常用來返回JSON
- 使用註解:@ResponseBody
- 使用對象返回,Json自動解析
-
@RequestMapping(value="/byid2") public @ResponseBody User findById2(int id){ User user = new User(); user.setId(id); user.setName("小霞"); user.setPhone("188"); //這裏可以使用JSON工具轉換爲字符串 return user; }
- 需要jackson-all-1.8.10.jar包,否則無法解析該類對象
-
- 接收JSON類型的對象
- 創建一個Controller方法
- 該方法的參數上必須加上註釋“@RequestBody”
-
@RequestMapping("/receive") public void receive(@RequestBody String name){ String str = "welcome "+name; System.out.println(str); }
-
-
注意:
- @RequestBody接收的是一個Json對象的字符串,而不是一個Json對象
- 用 JSON.stringify(data)的方式就能將對象變成字符串
-
<script type="text/javascript"> function sendJson(){ //創建對象 var user={ name:"lisa", age:22, phone:18898472345 } // 把JS當中的對象轉換成爲字符串 // 1、jquery.param name="小麗"&phone="110"&age=20 // 2、json字符串 // 3、在Controller中需要接收一個JSON的字符串,不能直接接收JSON對象 var str = JSON.stringify(user); $.ajax({ type:"post", url:"receive2.action", contentType:'application/json;charset=utf-8', data:str, success: function(data){ $("#h").html(data); } }); }</script>
- Controller中處理
-
@RequestMapping("/receive2") public @ResponseBody String receive2(@RequestBody User user) { String str =user.getName(); System.out.println(str); return str; }
- 解決中文亂碼問題:
-
/* * 中文亂碼問題得到解決 * 原理: 手動給對應的Accept返回制定格式編碼數據。 * 發現produces設置多個Accept只有第一個的charset是有用的, */ @RequestMapping(value = "/receive3", produces={"text/html;charset=UTF-8;","application/json;"}) public @ResponseBody String receive3(@RequestBody String name) { String str = "welcome " + name; System.out.println(str); return str; }
-
- 將集合轉換成爲一個JSON類型的字符串
-
@RequestMapping(value="/receive3",produces={"text/html;charset=UTF-8;","application/json;"}) public @ResponseBody String receive3(@RequestBody String name){ String str = "welcome : "+ name; List<User> list = new ArrayList<>(); list.add(new User("zs",12)); list.add(new User("ls",13)); list.add(new User("ww",14)); list.add(new User("zl",15)); // 使用阿里巴巴的fastjson.jar return JSONArray.toJSONString(list); }
-
- 在JS當中,將JSON格式的字符串轉換成爲一個JSON對象
-
$.ajax({ type:"post", url:"receive3.action", data:n, contentType:'application/json;charset=utf-8', success:function(data){ // 返回響應的字符串,需要轉換成爲JSON對象 console.log(data); $("#s").html(data); var json = JSON.parse(data); var html = ""; $.each(json,function(i,item){ html += "<li><span>"+i+"</span>" html += "<strong>"+item.name+"</strong></li>"; }) $("#d").html(html); } });
-
- Springmvc攔截器
- 概念:
- Spring Web MVC的處理器攔截器
- 類似於Servlet開發中的過濾器Filter,用於對處理器進行預處理和後處理。
- 常見的應用場景
- 日誌記錄:記錄請求信息的日誌,以便進行信息監控、信息統計、計算PV(Page View)等。
- 權限檢查:如登錄檢測,進入處理器檢測檢測是否登錄,如果沒有直接返回到登錄頁面;
- 性能監控:有時候系統在某段時間莫名其妙的慢,可以通過攔截器在進入處理器之前記錄開始時間,在處理完後記錄結束時間,從而得到該請求的處理時間(如果有反向代理,如apache可以自動記錄);
- 通用行爲:讀取cookie得到用戶信息並將用戶對象放入請求,從而方便後續流程使用,還有如提取Locale、Theme信息等,只要是多個處理器都需要的即可使用攔截器實現。
- OpenSessionInView:如Hibernate,在進入處理器打開Session,在完成後關閉Session。本質也是AOP(面向切面編程),也就是說符合橫切關注點的所有功能都可以放入攔截器實現。
- 概念:
- Springmvc攔截器和過濾器的區別
- 攔截器的配置
- 在Springmvc-servlet.xml中增加
-
<!-- 攔截器 --> <mvc:interceptors> <!-- 多個攔截器,順序執行 --> <mvc:interceptor> <mvc:mapping path="/entryOrJsonController/*" /> <bean class="com.wy.interceptor.CommonInterceptor"></bean> </mvc:interceptor> </mvc:interceptors>
- 創建攔截器
-
package org.springframework.web.servlet; public interface HandlerInterceptor { boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception; void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; void afterCompletion(HttpServletRequest request, HttpServletResponse response,Object handler, Exception ex) throws Exception; }
-
- 開發步驟
- 創建Interceptor,實現:HandlerInterceptor接口
- 注意:
- HandlerInterceptor的包:org.springframework.web.servlet
- preHandle方法必須返回true否則不能繼續
- return true;
- 注意:
- 配置springmvc-servlet.xml
-
<mvc:interceptors> <bean class="cn.smbms.interceptor.MyInterceptor"></bean> <!-- 攔截所有springmvc的url! --> </mvc:interceptors>
-
- 創建Interceptor,實現:HandlerInterceptor接口
- 多個攔截器的執行順序
覺得有點用記得給我點贊哦!
這篇文章就到這裏啦,如果覺得有收穫的話,不妨給一個贊喔;文章中涉及的內容肯定是不全面的,歡迎大家評論區留言補充。