1.什麼是SpringMvc?
Spring MVC是一個基於MVC(Model view Controller)模式的WEB框架,它解決WEB開發中常見的問題(參數接收、文件上傳、表單驗證、國際化、等等),使用非常簡單,SpringMvc作爲Spring中的一個模塊,可以與Spring無縫集成,爲應用程序中的Web層(表現層)提出的一套優秀的解決方案。
2.SpringMVC入門
(1)準備Spring環境: SpringMVC以Spring爲核心,而Spring最核心的模塊是IOC/DI容器,也就是SpringMVC的核心類和控制器要交給Spring管理。故項目中擁有Spring的運行環境.
(2) 準備SpringMVC jar包。
spring-webmvc-4.1.2.RELEASE.jar SpringMVC的jar文件。
spring-web-4.1.2.RELEASE.jar Spring對Web項目運行的支持。
(3)在web.xml中配置核心控制器 DispatcherServlet
這裏是web.xml中的類容:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>springmvc</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 1.配置所有的請求均要到達核心控制器(dispatcherServlet)裏去 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 啓動springmvc的核心控制器的時候,就初始化加載springmvc的配置文件 --> <!-- 一般spring的配置文件都在放在src中或者resource文件中 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-mvc.xml</param-value> </init-param> <!-- DispatcherServlet啓動比較耗時,在啓動加載文件的時候就進行加載 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 支持UTF-8編碼 --> <filter> <filter-name>characterEncoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
這裏是 applicationContext-mvc.xml 類容:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 測試spring的環境:--> <bean id="mybean" class="java.util.Date"></bean> <!-- 開啓Spring的註解的掃描:@Controller @Service @Repository @Component等 。默認存在--> <context:annotation-config /> <!-- 組件掃描路徑 --> <context:component-scan base-package="com.gs"/> <!-- 開啓springMVC的默認處理控制器 :處理靜態資源 --> <mvc:default-servlet-handler /> <!-- 開啓Springmvc的註解驅動:掃描@RequestMapping等註解 --> <mvc:annotation-driven/> <!-- springmvc的映射配置文件 --> <bean id="/hello1" class="com.gs.controller.HelloController"/> <bean id="/hello2" class="com.gs.controller.HandlerController"/> <!-- 配置文件上傳解析器,id="multipartResolver",這個id不能亂寫 設置一個maxUploadSize屬性,就是上傳文件的大小 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize"> <value>2000000000</value> </property> </bean> </beans>
注意:
1.一般spring的配置文件applicationContext-mvc.xml 都在放在src中或者resource文件中,我們可以通過web.xml配置告訴SpringMVC我們的配置文件路徑。
<init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-mvc.xml</param-value> </init-param>
2. 如果我們把spring的配置文件放在 WEB-INF 文件夾中,不需要在web.xml中配置上面代碼。 但是:
啓動Tomcat服務器的時候會初始化SpringMVC中的DispatcherServlet,而這個DispatcherServlet會根據配置文件初始化Spring容器,默認配置文件路徑爲:/WEB-INF/<servlet-name>-servlet.xml。
故:把配置文件更名爲springmvc-servlet.xml。
3. springmvc 控制器三種實現方式
① 實現Controller接口重寫 handleRequest(HttpServletRequest req, HttpServletResponse resp)方法,返回值爲 ModelAndView的對象,
並且還要將該類交給spring管理,配置的id的值就是該控制器的訪問路徑
public class HelloController implements Controller{ @Override public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception { //ModelAndView對象是springmvc控制器中的一個對象,用於封裝數據模型和返回頁面視圖 ModelAndView mv = new ModelAndView(); mv.setViewName("/jsp/index.jsp"); return mv; } }
② 實現HttpRequestHandler接口 重寫 handleRequest(HttpServletRequest req, HttpServletResponse resp)方法,沒有返回值。
並且還要將該類交給spring管理,配置的id的值就是該控制器的訪問路徑
public class HandlerController implements HttpRequestHandler { @Override public void handleRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //ModelAndView對象是springmvc控制器中的一個對象,用於封裝數據模型和返回頁面視圖 ModelAndView mv = new ModelAndView(); mv.setViewName("/jsp/index.jsp"); } }
③ 普通類(pojo)和註解 @RequestMapping
首先要開啓SprigMVC註解支持:
<!-- 開啓Spring的註解的掃描:@Controller @Service @Repository @Component等 。默認存在--> <context:annotation-config /> <!-- 組件掃描路徑 --> <context:component-scan base-package="com.gs"/> <!-- 開啓springMVC的默認處理控制器 :處理靜態資源 --> <mvc:default-servlet-handler /> <!-- 開啓Springmvc的註解驅動:掃描@RequestMapping等註解 --> <mvc:annotation-driven/>
@Controller @RequestMapping("/pojo") public class PojoController { @RequestMapping("/add") public String addddddddddd(){ //訪問該方法的具體路徑是 /pojo/add System.out.println("進來了"); return "/jsp/index.jsp"; } }
4. springmvc 控制器常用操作:
接收頁面傳遞參數、綁定數據到頁面、返回json數據、文件上傳、文件下載等
參數接收,首先要考慮亂碼問題(Post請求才有問題)。然而springmvc框架本身沒有處理請求編碼,但是spring框架爲我們提供了一個請求編碼過濾器,我們在web.xml配置一個請求編碼過濾器。
<!-- 支持UTF-8編碼 --> <filter> <filter-name>characterEncoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
1. 參數接收方式
① 通過控制器的執行方法參數來接收普通參數
② 通過Domain模型對象來接收
③ 通過傳統的HttpServletRequest接收
④ 通過url中的參數接收(restfull風格) @PathVariable("id")轉換
2. 數據傳遞
就是Controller往前臺(頁面)傳遞數據
① 通過ModelAndView對象傳遞
② 通過Model對象傳遞
③ 通過request對象傳遞
④ 通過返回值傳遞
具體代碼如下:
@Controller @RequestMapping("/user") public class UserController { // 1. 通過控制器的執行方法參數來接收普通參數 @RequestMapping("/add1") public String add111(@RequestParam("username") String name1, @RequestParam("age")String age1) { System.out.println( name1 +","+ age1 ); return "/jsp/index.jsp"; } // 2. 通過模型對象來接收(常用) ,形參中提供接受數據的模型對象. @RequestMapping("/add2") public String add222(User u) { System.out.println(u); return "/jsp/index.jsp"; } // 3. 接收url地址欄中參數的請求,(用戶請求參數值) @RequestMapping("/add3/{a}") public String add333(@PathVariable("a")Long id) { System.out.println(id); return "/jsp/index.jsp"; } // 4. 通過傳統的HttpServletRequest接收 // 4.1 將數據返回到前臺頁面 // 方式 1. 通過ModelAndView對象傳遞 @RequestMapping("/add401") public ModelAndView service(HttpServletRequest req,HttpServletResponse resp) { System.out.println(req.getParameter("username"));//獲取前臺頁面的數據 //將數據返回到前臺頁面 //方式一: ModelAndView mv = new ModelAndView(); mv.addObject("msg", "登陸成功401"); mv.addObject("user",new User("TOM",401)); mv.setViewName("../jsp/index.jsp"); return mv; } //4.2 通過Model對象傳遞 @RequestMapping("/add402") public String add4022(Model model) { //將數據返回到前臺頁面 //方式二: model.addAttribute("msg", "登錄成功402"); model.addAttribute("user", new User("TOM",402)); return "/jsp/index.jsp"; } //4.3 通過request對象傳遞 @RequestMapping("/add403") public String add4033(ServletRequest request) { //將數據返回到前臺頁面 //方式三: request.setAttribute("msg", "登錄成功403"); request.setAttribute("user", new User("TOM",403)); return "/jsp/index.jsp"; } //4.4 通過返回值傳遞 @RequestMapping("/add404") public User add4044() { //將數據返回到前臺頁面 //方式四: User u = new User("TOM",404); return u; } }
3. 返回json數據 主要在方法上加上:@ResponseBody //返回值以json數據格式進行返回
對日期格式的特殊處理(後面要用到的知識)
從後臺向前臺:
默認返回的日期格式爲時間戳,而在前臺我們希望顯示出指定規則的日期字符串。如:
默認:{"name":"小明哥","birthdate":121223223}
期望: {"name":"小明哥","birthdate":"2025-12-12 14:12:12"}
在日期get屬性,字段上,添加一個格式化註解
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
從前臺向後臺:
在後臺模型的setter方法上,添加註解
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
訪問地址:localhost:8080/jsonV587?birthDay=2017-06-13 16:50:53
4. 文件下載:
@RequestMapping("/filedownload/{name}") public void download(@PathVariable("name")String filename,HttpServletRequest req,HttpServletResponse resp) throws IOException { //設置下載文件的名稱(通過控制器下載文件時,瀏覽器可以顯示你要下載的文件的文件名稱) resp.setHeader("Content-Disposition","attachment;filename="+filename+".jpg"); //獲取文件的輸出流 OutputStream out = resp.getOutputStream(); //獲取下載文件的地址 String filePath ="F:/workspace/springMVC_day01/WebContent/download/"+filename+".jpg"; //獲取文件輸入流 FileInputStream fis = new FileInputStream(filePath); //文件流拷貝 IOUtils.copy(fis, out); }
5.文件上傳:
@RequestMapping("/fileupload") public String fileupload(String name,MultipartFile file,HttpServletRequest request) throws FileNotFoundException, IOException { System.out.println(name); System.out.println("進行文件上傳"); //1.獲取原始的文件名 String oldFileName = file.getOriginalFilename(); //2.獲取文件的後綴名 String extName = FilenameUtils.getExtension(oldFileName); //3. 生成一個隨機的文件名 String uuidname = UUID.randomUUID().toString(); String fileName = uuidname+","+extName; //4.設置文件保存的路徑 String fileDir = request.getServletContext().getRealPath("/upload"); System.out.println(fileDir); File filed = new File(fileDir,fileName); if(!filed.getParentFile().exists()) { filed.getParentFile().mkdirs(); } //5. 將數據以流的方式寫入該文件中 IOUtils.copy(file.getInputStream(), new FileOutputStream(filed)); return "../jsp/index.jsp"; }
5. SpringMVC的執行流程
-
一個請求匹配前端控制器 DispatcherServlet 的請求映射路徑(在 web.xml中指定), WEB 容器將該請求轉交給 DispatcherServlet 處理
-
DispatcherServlet 接收到請求後, 將根據 請求信息 交給 處理器映射器 (HandlerMapping)
-
HandlerMapping 根據用戶的url請求 查找匹配該url的 Handler,並返回一個執行鏈
-
DispatcherServlet 再請求 處理器適配器(HandlerAdapter) 調用相應的 Handler 進行處理並返回 ModelAndView 給 DispatcherServlet
-
DispatcherServlet 將 ModelAndView 請求 ViewReslover(視圖解析器)解析,返回具體 View
-
DispatcherServlet 對 View 進行渲染視圖(即將模型數據填充至視圖中),並將頁面響應給用戶。
組件說明:
-
DispatcherServlet:前端控制器
用戶請求到達前端控制器,它就相當於mvc模式中的c,dispatcherServlet是整個流程控制的中心,
由它調用其它組件處理用戶的請求,dispatcherServlet的存在降低了組件之間的耦合性。
-
HandlerMapping:處理器映射器
HandlerMapping負責根據用戶請求url找到Handler即處理器,springmvc提供了不同的映射器實現不同的映射方式,
例如:配置文件方式,實現接口方式,註解方式等。
-
Handler:處理器
Handler 是繼DispatcherServlet前端控制器的後端控制器,在DispatcherServlet的控制下Handler對具體的用戶請求進行處理。
由於Handler涉及到具體的用戶業務請求,所以一般情況需要程序員根據業務需求開發Handler。
-
HandlAdapter:處理器適配器
通過HandlerAdapter對處理器進行執行,這是適配器模式的應用,通過擴展適配器可以對更多類型的處理器進行執行。
-
ViewResolver:視圖解析器
View Resolver負責將處理結果生成View視圖,View Resolver首先根據邏輯視圖名解析成物理視圖名即具體的頁面地址,
再生成View視圖對象,最後對View進行渲染將處理結果通過頁面展示給用戶。
-
View:視圖
springmvc框架提供了很多的View視圖類型的支持,包括:jstlView、freemarkerView、pdfView等。我們最常用的視圖就是jsp。