springMVC框架學習安排
目錄
第一天
1. MVC基本概念
由圖可見MVC架構和我們之前所學的spring和MyBatis可以完美銜接,也是web應用開發必不可少的一部分,springMVC是一個MVC設計模型的一個框架。
三層框架的執行流程:
controller接受瀏覽器的請求,調用model可以將其封裝成JavaBean對象,發送給業務層處理,業務層又可以調用持久層與數據庫交互,將返回結果發送給表現層,封裝成JSP或者其它的視圖,響應給瀏覽器。
1.springMVC的基本概述
1.什麼是springMVC
springMVC 是一種基於Java的實現MVC設計模型的請求驅動類型的輕量級Web框架,
屬於Spring FrameWork的後續產品,已經融合在Spring Web Flow裏面。
Spring框架提供了構建Web應用程序的全功能MVC模塊。使用Spring 可插入的MVC
架構,從而在使用Spring 進行WEB開發時,可以選擇使用Spring的Spring MVC
框架或集成其他MVC開發框架,如Struts1(現在一般不用),Struts2等。
springMVC 已經成爲了主流的MVC框架之一,並且隨着spring3.0的發佈,
全面超越了struts2,成爲了最優秀的MVC框架。
它通過一套註解,讓一個簡單的Java類成爲處理請求的控制器,
並且無需實現任何接口,同時它還支持RESTful編程風格。
2. springMVC的優勢
- 清晰的角色劃分:
前端控制器(DispatcherServlet)
請求到處理器映射(HandlerMapping)
處理器適配器(HandlerAdapter)
視圖解析器(ViewResolver)
處理器或頁面控制器(Controller)
驗證器( Validator)
命令對象(Command 請求參數綁定到的對象就叫命令對象)
表單對象(Form Object 提供給表單展示和提交到的對象就叫表單對象)。 - 分工明確,而且擴展點相當靈活,可以很容易擴展,雖然幾乎不需要。
- 由於命令對象就是一個 POJO,無需繼承框架特定 API,可以使用命令對象直接作爲業務對象。
- 和 Spring 其他框架無縫集成,是其它 Web 框架所不具備的。
- 可適配,通過 HandlerAdapter 可以支持任意的類作爲處理器。
- 可定製性,HandlerMapping、ViewResolver 等能夠非常簡單的定製。
- 功能強大的數據驗證、格式化、綁定機制。
- 利用 Spring 提供的 Mock 對象能夠非常簡單的進行 Web 層單元測試。
- 本地化、主題的解析的支持,使我們更容易進行國際化和主題的切換。
- 強大的 JSP 標籤庫,使 JSP 編寫更容易。
………………還有比如RESTful風格的支持、簡單的文件上傳、約定大於配置的契約式編程支持、基於註解的零配
置支持等等。
3. springMVC和struts2的區別(面試問題)
共同點:
它們都是表現層框架,都是基於 MVC 模型編寫的。
它們的底層都離不開原始 ServletAPI。
它們處理請求的機制都是一個核心控制器。
區別:
Spring MVC 的入口是 Servlet, 而 Struts2 是 Filter
Spring MVC 是基於方法設計的,而 Struts2 是基於類,Struts2 每次執行都會創建一個動作類。所
以 Spring MVC 會稍微比 Struts2 快些。
Spring MVC 使用更加簡潔,同時還支持 JSR303, 處理 ajax 的請求更方便
(JSR303 是一套 JavaBean 參數校驗的標準,它定義了很多常用的校驗註解,我們可以直接將這些注
解加在我們 JavaBean 的屬性上面,就可以在需要校驗的時候進行校驗了。)
Struts2 的 OGNL 表達式使頁面的開發效率相比 Spring MVC 更高些,但執行效率並沒有比 JSTL 提
升,尤其是 struts2 的表單標籤,遠沒有 html 執行效率高。
2. springMVC的入門
-
入門案例需求分析
-
編寫代碼
- 創建maven工程,選擇webapp項目
- pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.liuzeyu</groupId> <artifactId>day03_springMVC01_start</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>day03_springMVC01_start Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <!--spring版本綁定--> <spring.version>5.0.2.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <finalName>day03_springMVC01_start</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
- controller控制器處理
添加Java和resource文件完善maven項目的目錄結構
@RequestMapping註解的作用是用於建立請求URL和處理請求方法之間的對應關係。 - spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--配置創建springIOC容器時要掃描的包--> <context:component-scan base-package="com.liuzeyu"></context:component-scan> <!--配置視圖解析器--> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"></property> <property name="suffix" value=".jsp"></property> </bean> <!--配置spring開啓註解mvc的支持--> <mvc:annotation-driven></mvc:annotation-driven> </beans>
- 配置servlet
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!--配置servlet--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--servlet啓動後需要加載的spring配置文件--> <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>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
- index.jsp與success.jsp
<%@page contentType="text/html; charset=UTF-8" language="java" %> <html> <head> <title>springmvc入門</title> </head> <body> <h3>入門程序</h3> <a href="hello">請求</a> </body> </html>
<%@page contentType="text/html; charset=UTF-8" language="java" %> <html> <head> <title>入門成功</title> </head> <body> <h2>springmvc入門成功</h2> </body> </html>
- springMVC執行流程
注意:@RequestMapping的path屬性和方法執行的return 可以不以 / 開頭,內部已經對其進行配置。
springMVC內部執行的詳細信息
服務器一經啓動,DisPatcherServlet對象(前端控制器)被創建,springMVC.xml被加載,HelloMVC對象也被創建。
當我們點擊a標籤後,帶有uri = /hello的請求被髮到了前端控制器,它會帶引這個請求去尋找處理器映射器,找到要執行的方法sayHello並返回(等下才要執行),當然前端控制器是不會執行這個方法,它會再次將這個結果發送到處理器適配器。
處理器適配器會適配controller下任何的方法,處理器適配器又會發送到處理器這個組件進行方法的執行與返回,執行後返回ModelAndView給處理器適配器,處理器適配器又會將其返回到前端控制器,前端控制器將這個結果發送到視圖解析器ViewResolver。
視圖解析器解析完之後又會將結果返回View前端控制器,前端控制器將View發送給View視圖組件解析,視圖將其解析成瀏覽器可以識別的出來的文件進行展示。
1. 涉及到組件
1. DispatcherServlet:前端控制器
用戶的請求到達前端控制器器後,DispatcherServlet對象它就相當於mvc模式執行流程的控制中心,它調用其它組件處理用戶的請求,前端控制器的存在降低了組件之間的耦合性。
2. HandlerMapping:處理器映射器
HandlerMapping負責根據用戶請求找到Handler,即處理器,springMVC提供了不同的映射器實現不同的映射方式。例如配置文件方式,實現接口方式,註解方式等。
3. Handler:處理器
處理器是我們開發中要編寫的具體業務控制器,由前端控制器把用戶請求發送到處理器,由處理器將用戶的請求進行業務處理。
4. HandlAdapter:處理器適配器
通過處理器適配器對處理器進行執行,這是適配器模式的應用,通過擴展適配器可以對更多類型的處理器進行執行
上圖是電腦外接顯示器的適配器,可以實現電腦連接不同的顯示屏。
5. View Resolver:視圖解析器
View Resolver解析器將處理結果生成視圖View,View Resolver首先根據邏輯視圖名解析成物理視圖名,即具體的頁面地址,再生成view視圖對象,最後對view進行渲染將處理結果以頁面展示給前端
6. View視圖器
作用就是將頁面標籤或模型數據通過頁面展示給前端,SpringMVC 框架提供了很多的 View 視圖類型的支持,包括:jstlView、freemarkerView、pdfView等。我們最常用的視圖就是 jsp。
2.< mvc:annotation-driven>說明
在springMVC的各個組件中,處理器映射器,處理器適配器,視圖解析器被稱爲springMVC的三大組件。
當在spring的配置文件中添加
<!--配置spring開啓註解mvc的支持-->
<mvc:annotation-driven></mvc:annotation-driven>
即默認開啓使 用RequestMappingHandlerMapping (處理映射器) 和
RequestMappingHandlerAdapter ( 處 理 適 配 器 )。
3.RequestMapping註解
查看源碼:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
作用:用於建立請求 URL 和處理請求方法之間的對應關係。
作用的位置:方法上,類上。
- path或value屬性擁有相同的作用
通常在實際開發中我們是類上和方法上配合使用,將xxx類模塊話,方法是細分的小模塊,賦值爲path或value屬性
如:- 賬戶模塊:
/account
/add
/account
/update
/account
/delete
… - 訂單模塊:
/order
/add
/order
/update
/order
/delete
紅色的部分就是把 RequsetMappding 寫在類上,使我們的 URL 更加精細。
方法上:
請求 URL 的第二級訪問目錄。
- 賬戶模塊:
示例:
@Controller
@RequestMapping("/user")
public class HelloMVC {
@RequestMapping(path = "hello")
public String sayHello(){
System.out.println("helloMVC........");
return "success";
}
@RequestMapping(path = "/good")
public String sayGood(){
System.out.println("goodMVC........");
return "success";
}
}
請求的url
<a href="user/hello">請求hello</a>
<a href="user/good">請求good</a>
經測試,在 @RequestMapping不管作用在哪裏,它的path路徑,都可以不用寫 / ,但是又時候爲了閱讀方便會寫上。
- method:用於指定請求的方式
// 這樣配置後通過a標籤發送的get請求的將不能執行到該方法
@RequestMapping(path = "hello",method = {RequestMethod.POST})
public String sayHello(){
System.out.println("helloMVC........");
return "success";
}
- params:用於指定限制請求參數的條件。它支持簡單的表達式。要求請求參數的 key 和 value 必須和配置的一模一樣。
@RequestMapping(path = "/good",params = {"username=liuzeyu"})
public String sayGood(){
System.out.println("goodMVC........");
return "success";
}
<a href="user/good?username=liuzeyu">請求good</a>
a標籤必須配置相應的key value的請求參數和請求值,方法纔可以被執行。
- header:用於指定限制請求消息頭的條件,瀏覽器消息頭的請求參數必須和配置一樣方法纔可以被執行。
問題:爲什麼註解屬性只傳一個時,屬性名可以不寫
- 如果註解只有一個屬性,那麼肯定是賦值給該屬性。
- 如果註解有多個屬性,而且前提是這多個屬性都有默認值,那麼你不寫註解名賦值,會賦值給名字爲“value”這屬性。
- 如果註解有多個屬性,其中有沒有設置默認值的屬性,那麼當你不寫屬性名答進行賦值的時候,是會報錯的。
3. 請求參數的綁定
1. 請求參數綁定入門
- 新建控制器
@Controller
@RequestMapping("/params")
public class ParamsMVC {
/**
* 請求參數綁定入門
* @return
*/
@RequestMapping("basic")
public String basic(String username,String password){
System.out.println("basic..."+username+"---" +password);
return "success";
}
}
- 請求鏈接
<a href="params/basic?username=liuzeyu&password=123">請求參數綁定入門</a>
注意:請求參數一定要和方法的參數一致。
- 訪問127.0.0.1:8080/params/basic測試輸出
2. 請求參數綁定實體類型
- 準備實體類
public class Account {
private Integer id;
private String name;
private Double money;
private User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
", user=" + user +
'}';
}
}
public class User {
private String uname;
private Integer age;
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"uname='" + uname + '\'' +
", age=" + age +
'}';
}
}
- 編寫controller
@Controller
@RequestMapping("/params")
public class ParamsMVC {
/**
* 請求參數綁定實體類
* @return
*/
@RequestMapping("domain")
public String domain(Account account){
System.out.println(account);
return "success";
}
}
- jsp請求頁面
<form action="/params/domain" method="post">
賬戶id:<input type="text" name="id"><br>
賬戶公司:<input type="text" name="name"><br>
賬戶金額:<input type="text" name="money"><br>
用戶名:<input type="text" name="user.uname"><br>
年齡:<input type="text" name="user.age"><br>
<input type="submit" value="提交">
</form>
- 測試發現post方式存在參數值的中文問題
3. 請求參數中文問題
上述的中文問題可以通過配置攔截器來解決編碼問題,在web.xml中配置
<!--處理post請求的中文亂碼問題-->
<filter>
<filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
就可以解決post請求的中文問題。
4. 請求參數爲集合類型
- 爲Account添加集合屬性,並生成getXXX和setXXX方法
private List<User> list;
private Map<String,User> map;
- jsp文件
<form action="/params/domain" method="post">
賬戶id:<input type="text" name="id"><br>
賬戶公司:<input type="text" name="name"><br>
賬戶金額:<input type="text" name="money"><br>
用戶名:<input type="text" name="list[0].uname"><br>
年齡:<input type="text" name="list[0].age"><br>
<br>
用戶名:<input type="text" name="map['one'].uname"><br>
年齡:<input type="text" name="map['one'].age"><br>
<input type="submit" value="提交">
</form>
重點注意name屬性的寫法。
- 測試
@RequestMapping("collections")
public String collections(Account account){
System.out.println(account);
return "success";
}
5. 自定義類型轉換器
- 爲User類添加Date birthday屬性
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
- jsp文件
<form action="/params/date" method="post">
用戶名:<input type="text" name="uname"><br>
年齡:<input type="text" name="age"><br>
生日:<input type="text" name="birthday"><br>
<input type="submit" value="提交">
</form>
- controller層代碼
@RequestMapping("date")
public String stringTodata(User user){
System.out.println(user);
return "success";
}
- 測試發現如果輸入生日格式爲2020/4/27即可以將字符串封裝成Date對象,如果輸入字符串格式爲2017-4-27,則封裝失敗
解決方案
通過自定義類型轉換器來解決
-
實現spring框架核心包爲我們提供的接口converter並且編寫工具類
/** * Created by liuzeyu on 2020/4/27. * 實現字符串轉日期格式工具類 */ public class StringToDate implements Converter<String,Date>{ @Override public Date convert(String s) { if(s == null || s.length() == 0){ throw new RuntimeException("字符串不能爲空..."); } DateFormat df = new SimpleDateFormat("yyyy-mm-dd"); try { Date date = df.parse(s); return date; } catch (ParseException e) { throw new RuntimeException("日期轉換失敗..."); } } }
-
spring配置文件中配置,爲核心包中添加一個工具類
<!--配置自定義類型轉換器--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.liuzeyu.utils.StringToDate"></bean> </set> </property> </bean> <!--配置spring開啓註解mvc的支持--> <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
- 重新測試日期格式爲2020-4-27
- 重新測試日期格式爲2020-4-27
6. web層使用原生的servlet-api對象
- jsp文件
<form action="/params/servlet" method="post">
用戶名:<input type="text" name="username"><br>
密碼:<input type="text" name="password"><br>
<input type="submit" value="提交">
</form>
- 編寫controller代碼,只需要在參數中定義請求和響應的對象即可
/**
* 測試使用原生的servlet對象
* @return
*/
@RequestMapping("servlet")
public String servlet(HttpServletRequest request, HttpServletResponse response){
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println(username +":"+password);
return "success";
}
- 測試結果
4. springMVC常用的註解
1. @RequestParam
作用:把請求中的指定參數名稱給控制器參數賦值
屬性:
- value:請求參數名稱
- required:請求參數中是否提供該參數,默認是true表示必須提供,如果不提供將報錯。
使用實例:
<a href="anno/requestParam?username=liuzeyu">註解@RequestParam</a>
@RequestMapping("requestParam")
public String testRequestParam(@RequestParam(value = "username") String name,
@RequestParam(value = "age",required = false) Integer age){
System.out.println(name);
return "success";
}
其中age參數,發送請求時可以不用發送age,但必須發送?username=xxx
2. @RequestBody
**作用:**獲取請求體的內容,直接使用得到的時key=xxx&value=yyy。get請求方式不適用
。
屬性:
required:是否必須有請求體,默認爲true,當爲true時,get請求會報錯。當請求爲false時,get獲取到的爲null
使用實例:
<form action="anno/requestBody" method="post">
用戶名:<input type="text" name="username"><br>
密碼:<input type="text" name="password"><br>
<input type="submit" value="提交">
</form>
<br>
<%--@RequestBody不適用於get請求--%>
<a href="anno/requestBody?username=liuzeyu&&password=80">註解@RequestBody</a>
@RequestMapping("requestBody")
public String testRequestBody(@RequestBody String body){
System.out.println(body);
return "success";
}
3. @PathVariable
引出REST編碼風格
什麼是 rest:
REST(英文:Representational State Transfer,簡稱 REST)描述了一個架構樣式的網絡系統,
比如 web 應用程序。它首次出現在 2000 年 Roy Fielding 的博士論文中,他是 HTTP 規範的主要編寫者之
一。在目前主流的三種 Web 服務交互方案中,REST 相比於 SOAP(Simple Object Access protocol,簡單
對象訪問協議)以及 XML-RPC 更加簡單明瞭,無論是對 URL 的處理還是對 Payload 的編碼,REST 都傾向於用更
加簡單輕量的方法設計和實現。值得注意的是 REST 並沒有一個明確的標準,而更像是一種設計的風格。
它本身並沒有什麼實用性,其核心價值在於如何設計出符合 REST 風格的網絡接口。
restful 的優點
它結構清晰、符合標準、易於理解、擴展方便,所以正得到越來越多網站的採用。
restful 的特性:
資源(Resources):網絡上的一個實體,或者說是網絡上的一個具體信息。
它可以是一段文本、一張圖片、一首歌曲、一種服務,總之就是一個具體的存在。可以用一個 URI(統一
資源定位符)指向它,每種資源對應一個特定的 URI 。要
獲取這個資源,訪問它的 URI 就可以,因此 URI 即爲每一個資源的獨一無二的識別符。
表現層(Representation):把資源具體呈現出來的形式,叫做它的表現層 (Representation)。
比如,文本可以用 txt 格式表現,也可以用 HTML 格式、XML 格式、JSON 格式表現,甚至可以採用二
進制格式。
狀態轉化(State Transfer):每 發出一個請求,就代表了客戶端和服務器的一次交互過程。
HTTP 協議,是一個無狀態協議,即所有的狀態都保存在服務器端。因此,如果客戶端想要操作服務器,
必須通過某種手段,讓服務器端發生“狀態轉化”(State Transfer)。而這種轉化是建立在表現層之上的,所以
就是 “表現層狀態轉化”。具體說,就是 HTTP 協議裏面,四個表示操作方式的動詞:GET 、POST 、PUT、
DELETE。它們分別對應四種基本操作:GET 用來獲取資源,POST 用來新建資源,PUT 用來更新資源,DELETE 用來
刪除資源。
restful 的示例:
/account/1 HTTP GET : 得到 id = 1 的 account
/account/1 HTTP DELETE: 刪除 id = 1 的 account
/account/1 HTTP PUT: 更新 id = 1 的 account
/account HTTP POST: 新增 account
作用:用於綁定url中的佔位符,例如url中的/delete/{id}
,這個{id}
就是佔位符
屬性:
- value:用於指定url的佔位符名稱
- required:是否必須提供佔位符
使用示例:
<a href="anno/pathVariable/10">註解@PathVariable</a>
@RequestMapping("pathVariable/{id}")
public String testPathVariable(@PathVariable Integer id){
System.out.println(id); //10
return "success";
}
4. @RequestHeader
作用:用戶獲取請求消息頭
屬性:
- value:提供消息頭名稱
- required:是否必須有此消息頭
注:實際開發中並不常用。
示例:
<a href="anno/requestHeader">註解@RequestHeader</a>
@RequestMapping("requestHeader")
public String testRequestHeader(@RequestHeader(value = "User-Agent") String header,
@RequestHeader(value = "date",required = false) String date){
System.out.println(header);
System.out.println(date);
return "success";
}
輸出:(date並不包含在請求頭中)
5. @CookieValue
作用:用於把指定的cookie名稱值傳入控制器的方法參數
屬性:
- value:提供指定的cookie名稱
- required:是否必須有此cookie
<a href="anno/cookieValue">註解@CookieValue</a>
@RequestMapping("cookieValue")
public String testCookieValue(@CookieValue(value = "JSESSIONID",required = false) String cookieValue){
System.out.println(cookieValue);
return "success";
}
輸出:
6. @ModelAttribute
作用:該註解是springMVC 4.3之後加入的,它可以用於修飾方法和參數
屬性:
value:用於獲取數據的key,key可以是POJO的屬性名稱,也可以是map結構的key。
應用場景:當表單提交數據不是完整的實體類數據時,保證沒有提交的數據可以使用數據庫原來的數據。
例如:
我們在更新一個用戶的數據時,用戶有一個字段是不允許被修改的,我們提交表單也沒有該字段。該字段從數據庫中獲取的,於是我們可以先從數據庫中獲取到,之後更新到新增的到用戶。
示例1:ModelAttribute 修飾方法不帶返回值:
<form action="anno/modelAttribute2" method="post">
用戶名:<input type="text" name="uname"><br>
密碼:<input type="text" name="age"><br>
<input type="submit" value="提交">
</form>
@RequestMapping("modelAttribute2")
public String testModelAttribute2(User user){
System.out.println("testModelAttribute2.....");
System.out.println(user);
return "success";
}
@ModelAttribute
public User showUser2(String username){
System.out.println("showUser2.....");
User user = new User();
user.setUname(username);
user.setAge(99999);
user.setBirthday(new Date());
return user;
}
輸出:
示例2:ModelAttribute 修飾方法帶返回值:
基於Map
<form action="anno/modelAttribute1" method="post">
用戶名:<input type="text" name="uname"><br>
密碼:<input type="text" name="age"><br>
<input type="submit" value="提交">
</form>
/**
* 註解@ModelAttribute:基於map
* @param user
* @return
*/
@RequestMapping("modelAttribute1")
public String testModelAttribute1(@ModelAttribute(value = "one") User user){
System.out.println("testModelAttribute1.....");
System.out.println(user);
return "success";
}
//會比testModelAttribute先執行
@ModelAttribute
public void showUser1(String username,Map<String,User> map){
System.out.println("showUser1.....");
User user = new User();
user.setUname(username);
user.setAge(9999);
user.setBirthday(new Date());
map.put("one",user);
}
輸出: