一種輕量級的、基於MVC的Web層應用框架。偏前端而不是基於業務邏輯層。Spring框架的一個後續產品。html
2)Spring框架結構圖(新版本):前端
1.新建Web工程,加入 jar 包java
spring-aop-4.0.0.RELEASE.jar spring-beans-4.0.0.RELEASE.jar spring-context-4.0.0.RELEASE.jar spring-core-4.0.0.RELEASE.jar spring-expression-4.0.0.RELEASE.jar commons-logging-1.1.3.jar spring-web-4.0.0.RELEASE.jar spring-webmvc-4.0.0.RELEASE.jar
2.在 web.xml 中配置 DispatcherServlet程序員
<!-- 配置SpringMVC核心控制器: --> <servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置DispatcherServlet的初始化參數:設置文件的路徑和文件名稱 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
3.加入 Spring MVC 的配置文件:springmvc.xmlweb
<!-- 設置掃描組件的包: -->` <context:component-scan base-package="com.hbuas.springmvc"/> <!-- 配置映射解析器:如何將控制器返回的結果字符串,轉換爲一個物理的視圖文件--> <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean>
這裏回顧一下知識點:ajax
4.須要建立一個入口頁面,index.jspspring
<a href="${pageContext.request.contextPath }/helloworld">Hello World</a>
5.編寫處理請求的處理器,並標識爲Controllerexpress
package com.hbuas.springmvc.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller //聲明Bean對象,爲一個控制器組件 public class HelloWorldController { /** * * 1. 使用 @RequestMapping 註解來映射請求的 URL * 2. 返回值會經過視圖解析器解析爲實際的物理視圖 */ @RequestMapping(value="/helloworld",method=RequestMethod.GET) public String helloworld(){ System.out.println("hello,world"); return "success"; } /** ** 如何跳轉呢? * 對於 InternalResourceViewResolver 視圖解析器, * 會作以下的解析: * 經過 prefix + returnVal + suffix 這樣的方式獲得實際的物理視圖, 而後作轉發操做. * /WEB-INF/views/success.jsp */ }
基本步驟:json
實驗代碼:數組
定義頁面連接
<a href="springmvc/helloworld">test</a>
定義控制器方法
@Controller @RequestMapping("/springmvc") public class HelloWorldController { @RequestMapping(value="/helloworld") public String helloworld(){ System.out.println("hello,world"); return "success"; } }
@RequestMapping 除了可使用請求 URL 映射請求外,還可使用請求方法、請求參數及請求頭映射請求.
@RequestMapping 的 value、method、params 及 heads 分別表示請求 URL、請求方法、請求參數及請求頭的映射條件,他們之間是與的關係,聯合使用多個條件可以讓請求映射更加精確化。
請求方式:GET 查詢 POST 添加 PUT 修改 DELETE 刪除
實驗代碼:
定義請求方式爲POST
@Controller @RequestMapping("/springmvc") public class SpringMVCController { @RequestMapping(value="/testMethord",method=RequestMethod.POST) public String testMethord(){ System.out.println("testMethord..."); return "success"; } }
以get方式請求
<a href="springmvc/testMethord">testMethord</a>
// 可使用 params 和 headers 來更加精確的映射請求. params 和 headers 支持簡單的表達式. @RequestMapping(value="/testParamsAndHeaders", params= {"username","age!=10"}, headers = { "Accept-Language=en-US,zh;q=0.8" }) public String testParamsAndHeaders(){ System.out.println("testParamsAndHeaders..."); return "success"; }
測試不正確的話會出現
警告: No matching handler method found for servlet request: path '/springmvc/testParamsAndHeaders', method 'GET', parameters map[[empty]]
?:匹配文件名中的一個字符
*:匹配文件名中的任意字符
**:** 匹配多層路徑
/user/*/createUser 匹配 /user/aaa/createUser或者/user/bbb/createUser 等 URL /user/**/createUser 匹配 /user/createUser或者/user/aaa/bbb/createUser 等 URL /user/createUser?? 匹配 /user/createUseraa或者/user/createUserbb 等 URL //@RequestMapping(value="/testAntPath/*/abc") //@RequestMapping(value="/testAntPath/**/abc") @RequestMapping(value="/testAntPath/abc??")
@PathVariable
帶佔位符的URL 是 Spring3.0 新增的功能,該功能在 SpringMVC 向 REST 目標挺進發展過程當中具備里程碑的意義
經過 @PathVariable 能夠將 URL 中佔位符參數綁定到控制器處理方法的入參中:
URL 中的 {xxx} 佔位符能夠經過 @PathVariable("xxx") 綁定到操做方法的入參中。
//@PathVariable 註解能夠將請求URL路徑中的請求參數,傳遞處處理請求方法的入參中 //瀏覽器的請求: testPathVariable/1001 @RequestMapping(value="/testPathVariable/{id}") public String testPathVariable(@PathVariable("id") Integer id){ System.out.println("testPathVariable...id="+id); return "success"; }
1)在處理方法入參處使用 @RequestParam 能夠把請求參數傳遞給請求方法
2)value:參數名
3)required:是否必須。默認爲 true, 表示請求參數中必須包含對應的參數,若不存在,將拋出異常
4)defaultValue: 默認值,當沒有傳遞參數時使用該值
/** * @RequestParam 註解用於映射請求參數 * value 用於映射請求參數名稱 * required 用於設置請求參數是否必須的 * defaultValue 設置默認值,當沒有傳遞參數時使用該值 */ @RequestMapping(value="/testRequestParam") public String testRequestParam( @RequestParam(value="username") String username, @RequestParam(value="age",required=false,defaultValue="0") int age){ System.out.println("testRequestParam - username="+username +",age="+age); return "success"; }
<!--測試 請求參數 @RequestParam 註解使用 --> <a href="springmvc/testRequestParam?username=admin&age=10">testRequestParam</a>
//瞭解: 映射請求頭信息 用法同 @RequestParam @RequestMapping(value="/testRequestHeader") public String testRequestHeader(@RequestHeader(value="Accept-Language") String al){ System.out.println("testRequestHeader - Accept-Language:"+al); return "success"; }
//瞭解:@CookieValue: 映射一個 Cookie 值. 屬性同 @RequestParam @RequestMapping("/testCookieValue") public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) { System.out.println("testCookieValue: sessionId: " + sessionId); return "success"; }
/** * Spring MVC 會按請求參數名和 POJO 屬性名進行自動匹配, 自動爲該對象填充屬性值。 * 支持級聯屬性 * 如:dept.deptId、dept.address.tel 等 */ @RequestMapping("/testPOJO") public String testPojo(User user) { System.out.println("testPojo: " + user); return "success"; }
<!-- 測試 POJO 對象傳參,支持級聯屬性 --> <form action=" testPOJO" method="POST"> username: <input type="text" name="username"/><br> password: <input type="password" name="password"/><br> email: <input type="text" name="email"/><br> age: <input type="text" name="age"/><br> city: <input type="text" name="address.city"/><br> province: <input type="text" name="address.province"/> <input type="submit" value="Submit"/> </form>
增長實體類
public class Address { private String province; private String city; |
public class User { private Integer id ; private String username; private String password; private String email; private int age; private Address address; |
SpringMVC 提供瞭如下幾種途徑輸出模型數據
控制器處理方法的返回值若是爲 ModelAndView, 則其既包含視圖信息,也包含模型數據信息。
private Object view; 視圖信息
private ModelMap model; 模型數據
2)添加模型數據:
MoelAndView addObject(String attributeName, Object attributeValue) 設置模型數據
ModelAndView addAllObject(Map<String, ?> modelMap)
3)設置視圖:
void setView(View view) 設置視圖對象
void setViewName(String viewName) 設置視圖名字
4)獲取模型數據
protected Map<String, Object> getModelInternal() 獲取模型數據
public ModelMap getModelMap()
public Map<String, Object> getModel()
實驗代碼:
/** * 目標方法的返回類型能夠是ModelAndView類型 * 其中包含視圖信息和模型數據信息 */ @RequestMapping("/testModelAndView") public ModelAndView testModelAndView(){ System.out.println("testModelAndView"); String viewName = "success"; ModelAndView mv = new ModelAndView(viewName ); mv.addObject("time",new Date().toString()); //實質上存放到request域中 return mv; }
Spring MVC 在內部使用了一個 org.springframework.ui.Model 接口存儲模型數據
具體使用步驟
2)Spring MVC 在調用方法前會建立一個隱含的模型對象做爲模型數據的存儲容器。
3)若是方法的入參爲 Map 或 Model 類型,Spring MVC 會將隱含模型的引用傳遞給這些入參。
4)在方法體內,開發者能夠經過這個入參對象訪問到模型中的全部數據,也能夠向模型中添加新的屬性數據
實驗代碼:
//目標方法的返回類型也能夠是一個Map類型參數(也能夠是Model,或ModelMap類型) @RequestMapping("/testMap") public String testMap(Map<String,Object> map){ //【重點】 System.out.println(map.getClass().getName()); map.put("names", Arrays.asList("Tom","Jerry","Kite")); return "success"; }
<!-- 測試 Map 做爲處理返回結果 --> <a href="springmvc/testMap">testMap</a>
<!--增長成功頁面,顯示結果--> names: ${requestScope.names }
注意問題:Map集合的泛型,key爲String,Value爲Object,而不是String
3.視圖對象由視圖解析器負責實例化。因爲視圖是無狀態的,因此他們不會有線程安全的問題
不論控制器返回一個String,ModelAndView,View都會轉換爲ModelAndView對象,由視圖解析器解析視圖,而後,進行頁面的跳轉。
@RequestMapping("/testRedirect") public String testRedirect(){ System.out.println("testRedirect"); return "redirect:/index.jsp"; //return "forward:/index.jsp"; }
轉發與重定向知識回顧:
區別 | 轉發forward() | 重定向sendRedirect() |
---|---|---|
根目錄 | 包含項目訪問地址 | 沒有項目訪問地址 |
地址欄 | 不會發生變化 | 會發生變化 |
哪裏跳轉 | 服務器端進行的跳轉 | 瀏覽器端進行的跳轉 |
請求域中數據 | 不會丟失 | 會丟失 |
springMVC處理json的四個條件:
一、導入jackson的jar
二、在springMVC的配置文件中開啓MVC驅動,<mvc:annotation-driven />
三、在處理ajax請求的方法上加上註解@ResponseBody
四、將要轉換爲json且響應到客戶端的數據,直接做爲該方法的返回值返回
@RequestMapping("/testJson") @ResponseBody public Collection<Employee> testJson() { Collection<Employee> emps = dao.getAll(); return emps; }
實例:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="UTF-8"></property> <property name="maxUploadSize" value="1024000"></property> </bean> |
<%@ 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="testUpload" method="post" enctype="multipart/form-data"> 文件: <input type="file" name="file"/><br><br> 描述: <input type="text" name="desc"/><br><br> <input type="submit" value="提交"/> </form> </body> </html> |
@Controller public class UploadHandler { @RequestMapping(value="/testUpload",method=RequestMethod.POST) public String testUpload( @RequestParam(value="desc",required=false) String desc, @RequestParam("file") MultipartFile multipartFile) throws IOException{ System.out.println("desc : "+desc); System.out.println("OriginalFilename : "+multipartFile.getOriginalFilename()); InputStream inputStream = multipartFile.getInputStream(); System.out.println("inputStream.available() : "+inputStream.available()); System.out.println("inputStream : "+inputStream); return "success"; } } |
DispatcherServlet 默認裝配的 HandlerExceptionResolver
能夠對一些特殊的異常進行處理,好比:
若是但願對全部異常進行統一處理,可使用 SimpleMappingExceptionResolver,它將異常類名映射爲視圖名,即發生異常時使用對應的視圖報告異常
1.用戶向服務器發送請求,請求被SpringMVC 前端控制器 DispatcherServlet捕獲;
2.DispatcherServlet對請求URL進行解析,獲得請求資源標識符(URI):
判斷請求URI對應的映射
不存在:
存在:
3.根據該URI,調用HandlerMapping得到該Handler配置的全部相關的對象(包括Handler對象以及Handler對象對應的攔截器),最後以HandlerExecutionChain對象的形式返回;
4.DispatcherServlet 根據得到的Handler,選擇一個合適的HandlerAdapter。
5.若是成功得到HandlerAdapter後,此時將開始執行攔截器的preHandler(...)方法【正向】
6.提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)方法,處理請求。在填充Handler的入參過程當中,根據你的配置,Spring將幫你作一些額外的工做:
7.Handler執行完成後,向DispatcherServlet 返回一個ModelAndView對象;
8.此時將開始執行攔截器的postHandle(...)方法【逆向】
9.根據返回的ModelAndView(此時會判斷是否存在異常:若是存在異常,則執行HandlerExceptionResolver進行異常處理)選擇一個適合的ViewResolver(必須是已經註冊到Spring容器中的ViewResolver)返回給DispatcherServlet,根據Model和View,來渲染視圖
10.在返回給客戶端時須要執行攔截器的AfterCompletion方法【逆向】
11.將渲染結果返回給客戶端
SpringMVC 的 IOC 容器中的 bean 能夠來引用 Spring IOC 容器中的 bean.反之則不行. Spring IOC 容器中的 bean 卻不能來引用 SpringMVC IOC 容器中的 bean
即 WEB 層容器能夠引用業務層容器的 Bean,而業務層容器卻訪問不到 WEB 層容器的 Bean