SpringMVC 簡(jiǎn)介
-
MVC 模式
MVC 是軟件工程中的一種軟件架構(gòu)模式乏屯,它是一種分離業(yè)務(wù)邏輯與顯示界面的開(kāi)發(fā)思想勃刨。
- M(model)模型:處理業(yè)務(wù)邏輯叽粹,封裝實(shí)體
- V(view) 視圖:展示內(nèi)容
- C(controller)控制器:負(fù)責(zé)調(diào)度分發(fā)(1.接收請(qǐng)求、2.調(diào)用模型溯乒、3.轉(zhuǎn)發(fā)到視圖)
-
SpringMVC 概述
SpringMVC 是一種基于 Java 的實(shí)現(xiàn) MVC 設(shè)計(jì)模式的輕量級(jí) Web 框架杯道,屬于Spring Framework 的后續(xù)產(chǎn)品匪煌,已經(jīng)融合在 Spring Web Flow 中责蝠。
SpringMVC 已經(jīng)成為目前最主流的 MVC 框架之一,并且隨著 Spring 3.0 的發(fā)布萎庭,全面超越 Struts 2霜医,成為最優(yōu)秀的 MVC 框架。它通過(guò)一套注解驳规,讓一個(gè)簡(jiǎn)單的 Java 類成為處理請(qǐng)求的控制器肴敛,而無(wú)須實(shí)現(xiàn)任何接口。同時(shí)它還支持 RESTful 編程風(fēng)格的請(qǐng)求吗购。
SpringMVC 的框架就是封裝了原來(lái) Servlet 中的共有行為医男;例如:參數(shù)封裝,視圖轉(zhuǎn)發(fā)等捻勉。
-
SpringMVC 快速入門(mén)
需求:客戶端發(fā)起請(qǐng)求镀梭,服務(wù)器接收請(qǐng)求,執(zhí)行邏輯并進(jìn)行視圖跳轉(zhuǎn)踱启。
步驟分析:
- 創(chuàng)建web項(xiàng)目报账,導(dǎo)入 SpringMVC 相關(guān)坐標(biāo)
- 配置 SpringMVC 前端控制器 DispatcherServlet
- 編寫(xiě) Controller 類和視圖頁(yè)面
- 使用注解配置 Controller 類中業(yè)務(wù)方法的映射地址
- 配置 SpringMVC 核心文件 spring-mvc.xml
1. 創(chuàng)建 web 項(xiàng)目,導(dǎo)入 SpringMVC 相關(guān)坐標(biāo)
<packaging>war</packaging>
<!-- 指定編碼及版本 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.11</java.version>
<maven.compiler.source>1.11</maven.compiler.source>
<maven.compiler.target>1.11</maven.compiler.target>
</properties>
<dependencies>
<!-- springMVC 坐標(biāo) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<!-- servlet 坐標(biāo) -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp 坐標(biāo) -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
...
</dependencies>
2. 配置 SpringMVC 前端控制器 DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- springMVC 的前端控制器:DispatcherServlet-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加載 springMVC 相關(guān)的配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--
在應(yīng)用啟動(dòng)時(shí)埠偿,就完成 servlet 的實(shí)例化及初始化操作透罢。
數(shù)字大于等于 0 時(shí),服務(wù)器啟動(dòng)時(shí)就加載并初始化 servlet;
數(shù)字越接近 0冠蒋,則優(yōu)先級(jí)越高
-->
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--
/ 和 /* 的區(qū)別:
/ 會(huì)匹配到所有的訪問(wèn)路徑羽圃,除了帶有 *.jsp 這樣的后綴名的路徑;
如可以匹配到 /login /add /update浊服,但 /a.jsp 不能匹配统屈。
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3. 編寫(xiě) Controller 類和視圖頁(yè)面
UserController.java
public class UserController {
public String quick() {
// 業(yè)務(wù)處理
System.out.println("SpringMVC Quick Start...");
// 頁(yè)面跳轉(zhuǎn) 請(qǐng)求轉(zhuǎn)發(fā)
return "/WEB-INF/pages/success.jsp";
}
}
/WEB-INF/pages/success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SUCCESS</title>
</head>
<body>
<h3>success... ${username}</h3>
<% System.out.println("Success...");%>
</body>
</html>
4. 使用注解配置 Controller 類中業(yè)務(wù)方法的映射地址
@Controller
public class UserController {
@RequestMapping("/quick")
public String quick() {
System.out.println("SpringMVC Quick Start...");
return "/WEB-INF/pages/success.jsp";
}
}
5. 配置 SpringMVC 核心文件 spring-mvc.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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/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">
<!-- IOC 注解掃描 -->
<context:component-scan base-package="com.zm.controller"/>
</beans>
-
web 工程執(zhí)行流程
客戶端(瀏覽器)發(fā)送請(qǐng)求到 Tomcat 服務(wù)器胚吁,Tomcat 服務(wù)器發(fā)送響應(yīng)到客戶端牙躺。
服務(wù)器的 Tomcat 引擎:
- 接受客戶端請(qǐng)求,解析請(qǐng)求資源地址
- 創(chuàng)建代表請(qǐng)求的 request 對(duì)象
- 創(chuàng)建代表響應(yīng) response 對(duì)象
- 調(diào)用目標(biāo)資源
- 獲得 response 中的內(nèi)容腕扶,組裝成 HTTP 響應(yīng)返回客戶端
服務(wù)器的 Web 應(yīng)用:
- 獲得請(qǐng)求資源地址
- 解析映射地址孽拷,找到對(duì)應(yīng)的處理器(Controller)
- 處理器執(zhí)行對(duì)應(yīng)的方法(進(jìn)行業(yè)務(wù)邏輯以及視圖跳轉(zhuǎn)操作),獲取被訪問(wèn)的真實(shí)資源
小結(jié)
- SpringMVC 是對(duì) MVC 設(shè)計(jì)模式的一種實(shí)現(xiàn)半抱,屬于輕量級(jí)的 WEB 框架脓恕。
- SpringMVC 的開(kāi)發(fā)步驟:
- 創(chuàng)建 web 項(xiàng)目,導(dǎo)入 SpringMVC 相關(guān)坐標(biāo)
- 配置 SpringMVC 前端控制器 DispatcherServlet
- 編寫(xiě) Controller 類和視圖頁(yè)面
- 使用注解配置 Controller 類中業(yè)務(wù)方法的映射地址
- 配置 SpringMVC 核心文件 spring-mvc.xml
SpringMVC 組件概述
-
SpringMVC 的執(zhí)行流程
- 用戶發(fā)送請(qǐng)求至前端控制器 DispatcherServlet窿侈。
- DispatcherServlet 收到請(qǐng)求調(diào)用 HandlerMapping 處理器映射器炼幔。
- 處理器映射器找到具體的處理器(可以根據(jù) xml 配置、注解進(jìn)行查找)史简,生成處理器對(duì)象及處理器攔截器(如果有則生成)一并返回給 DispatcherServlet乃秀。
- DispatcherServlet 調(diào)用 HandlerAdapter 處理器適配器。
- HandlerAdapter 經(jīng)過(guò)適配調(diào)用具體的處理器(Controller,也叫后端控制器)跺讯。
- Controller 執(zhí)行完成返回 ModelAndView枢贿。
- HandlerAdapter 將 controller 執(zhí)行結(jié)果 ModelAndView 返回給 DispatcherServlet。
- DispatcherServlet 將 ModelAndView 傳給 ViewReslover 視圖解析器刀脏。
- ViewReslover 解析后返回具體 View局荚。
- DispatcherServlet 根據(jù) View 進(jìn)行渲染視圖(即將模型數(shù)據(jù)填充至視圖中)。
- DispatcherServlet 將渲染后的視圖響應(yīng)響應(yīng)用戶愈污。
-
SpringMVC 組件解析
前端控制器:DispatcherServlet
用戶請(qǐng)求到達(dá)前端控制器耀态,它就相當(dāng)于 MVC 模式中的 C;DispatcherServlet 是整個(gè)流程控制的中心钙畔,由它調(diào)用其它組件處理用戶的請(qǐng)求茫陆;DispatcherServlet 的存在降低了組件之間的耦合性。處理器映射器:HandlerMapping
HandlerMapping 負(fù)責(zé)根據(jù)用戶請(qǐng)求找到 Handler 即處理器擎析;SpringMVC 提供了不同的映射器實(shí)現(xiàn)不同的映射方式簿盅,例如:配置文件方式、實(shí)現(xiàn)接口方式揍魂、注解方式等桨醋。處理器適配器:HandlerAdapter
通過(guò) HandlerAdapter 對(duì)處理器進(jìn)行執(zhí)行,這是適配器模式的應(yīng)用现斋,通過(guò)擴(kuò)展適配器可以對(duì)更多類型的處理器進(jìn)行執(zhí)行喜最。處理器:Handler【開(kāi)發(fā)者編寫(xiě)】
它是開(kāi)發(fā)中要編寫(xiě)的具體業(yè)務(wù)控制器;由 DispatcherServlet 把用戶請(qǐng)求轉(zhuǎn)發(fā)到 Handler庄蹋;由 Handler 對(duì)具體的用戶請(qǐng)求進(jìn)行處理瞬内。視圖解析器:ViewResolver
View Resolver 負(fù)責(zé)將處理結(jié)果生成 View 視圖;View Resolver 首先根據(jù)邏輯視圖名解析成物理視圖名限书,即具體的頁(yè)面地址虫蝶,再生成 View 視圖對(duì)象,最后對(duì) View 進(jìn)行渲染將處理結(jié)果通過(guò)頁(yè)面展示給用戶倦西。視圖:View 【開(kāi)發(fā)者編寫(xiě)】
SpringMVC 框架提供了很多的 View 視圖類型的支持能真,包括:jstlView、freemarkerView扰柠、pdfView等粉铐。最常用的視圖就是 jsp。一般情況下需要通過(guò)頁(yè)面標(biāo)簽或頁(yè)面模版技術(shù)將模型數(shù)據(jù)通過(guò)頁(yè)面展示給用戶卤档,需要由程序員根據(jù)業(yè)務(wù)需求開(kāi)發(fā)具體的頁(yè)面蝙泼。SpringMVC 中的三大組件是什么?
處理器映射器 HandlerMapping劝枣;
處理器適配器 HandlerAdapter汤踏;
視圖解析器 ViewResolver倡缠;
如果是四大組件,則加上前端控制器 DispatcherServlet茎活。
spring-mvc.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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/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">
<!-- IOC 注解掃描 -->
<context:component-scan base-package="com.zm.controller"/>
<!-- 處理器映射器-處理器適配器昙沦。進(jìn)行了功能的增強(qiáng):支持 json 的讀寫(xiě) -->
<mvc:annotation-driven/>
<!-- 視圖解析器:ViewResolver -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- success :解析邏輯視圖名,解析成具體的物理文件地址 /WEB-INF/pages/success.jsp -->
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
UserController.java
@RequestMapping("/quick")
public String quick() {
System.out.println("SpringMVC Quick Start...");
// 頁(yè)面跳轉(zhuǎn) 請(qǐng)求轉(zhuǎn)發(fā) 返回邏輯視圖名
return "success";
}
-
SpringMVC 注解解析
@Controller
SpringMVC 基于 Spring 容器载荔,所以在進(jìn)行 SpringMVC 操作時(shí)盾饮,需要將 Controller 存儲(chǔ)到 Spring 容器中,如果使用 @Controller 注解標(biāo)注的話懒熙,就需要使用:
<!-- 配置 IOC 注解掃描 -->
<context:component-scan base-package="com.zm.controller"/>
注意配置 SpringMVC 的 base package 只掃描 web 層的包丘损,其它包交給 Spring 容器掃描;這樣 SpringMVC 的容器就相當(dāng)于是 Spring 容器的一個(gè)子容器工扎。
@RequestMapping
* 作用:用于建立請(qǐng)求 URL 和處理請(qǐng)求方法之間的對(duì)應(yīng)關(guān)系
* 位置:
1. 類上:請(qǐng)求 URL 的第一級(jí)訪問(wèn)目錄徘钥。此處不寫(xiě)的話,就相當(dāng)于應(yīng)用的根目錄肢娘;寫(xiě)的話需要以 / 開(kāi)頭呈础。
它出現(xiàn)的目的是為了使 URL 可以按照模塊化管理:
用戶模塊
/user/add
/user/update
/user/delete
...
賬戶模塊
/account/add
/account/update
/account/delete
2. 方法上:請(qǐng)求 URL 的第二級(jí)訪問(wèn)目錄,和一級(jí)目錄組成一個(gè)完整的 URL 路徑橱健。
* 屬性:
1. value:用于指定請(qǐng)求的 URL而钞;它和 path 屬性的作用是一樣的
2. method:用來(lái)限定請(qǐng)求的方式
3. params:用來(lái)限定請(qǐng)求參數(shù)的條件
例如:
params={"accountName"} 表示請(qǐng)求參數(shù)中必須有 accountName
params={"money!100"} 表示請(qǐng)求參數(shù)中 money 不能是100
@Controller
@RequestMapping("/user") //一級(jí)訪問(wèn)目錄
public class UserController {
/**
* http://localhost:8080/springmvc_quickstart/user/quick?accountName=renda
*
* path :作用等同于 value,同樣是設(shè)置方法的映射地址
* method:用來(lái)限定請(qǐng)求的方式 RequestMethod.POST: 只能以 post 的請(qǐng)求方式訪問(wèn)該訪問(wèn)拘荡,其他請(qǐng)求方式會(huì)報(bào)錯(cuò)
* params:用來(lái)限定請(qǐng)求參數(shù)的條件 params={"accountName"} 表示請(qǐng)求參數(shù)中必須有 accountName
*/
@RequestMapping(
path = "/quick", // 二級(jí)訪問(wèn)目錄
method = {RequestMethod.POST, RequestMethod.GET},
params = {"accountName"})
public String quick() {
// 業(yè)務(wù)處理
System.out.println("SpringMVC Quick Start...");
// 頁(yè)面跳轉(zhuǎn) 請(qǐng)求轉(zhuǎn)發(fā) 返回邏輯視圖名
return "success";
}
}
-
小結(jié)
-- SpringMVC的三大組件
處理器映射器:HandlerMapping
處理器適配器:HandlerAdapter
視圖解析器:View Resolver-- 開(kāi)發(fā)者編寫(xiě)
處理器:Handler
視圖:View
SpringMVC 的請(qǐng)求
-
請(qǐng)求參數(shù)類型介紹
客戶端請(qǐng)求參數(shù)的格式是: name=value&name=value ...
服務(wù)器要獲取請(qǐng)求的參數(shù)的時(shí)候要進(jìn)行類型轉(zhuǎn)換臼节,有時(shí)還需要進(jìn)行數(shù)據(jù)的封裝
SpringMVC 可以接收如下類型的參數(shù):
基本類型參數(shù)
對(duì)象類型參數(shù)
數(shù)組類型參數(shù)
集合類型參數(shù)
-
獲取基本類型參數(shù)
Controller 中的業(yè)務(wù)方法的參數(shù)名稱要與請(qǐng)求參數(shù)的 name 一致,參數(shù)值會(huì)自動(dòng)映射匹配珊皿。并且能自動(dòng)做類型轉(zhuǎn)換网缝;自動(dòng)的類型轉(zhuǎn)換是指從 String 向其他類型的轉(zhuǎn)換。
requestParam.jsp
<%-- ${pageContext.request.contextPath} 動(dòng)態(tài)的來(lái)獲取當(dāng)前的項(xiàng)目路徑 - springmvc_quickstart蟋定;a 標(biāo)簽的請(qǐng)求方式:get 請(qǐng)求 --%>
<a href="${pageContext.request.contextPath}/user/simpleParam?id=1&username=杰克">
基本類型參數(shù)
</a>
在 UserController 中添加方法
@RequestMapping("/simpleParam")
public String simpleParam(Integer id, String username) {
System.out.println(id);
System.out.println(username);
return "success";
}
-
獲取對(duì)象類型參數(shù)
Controller 中的業(yè)務(wù)方法參數(shù)的 POJO 屬性名與請(qǐng)求參數(shù)的 name 一致粉臊,參數(shù)值會(huì)自動(dòng)映射匹配。
requestParam.jsp
<%-- form 表單溢吻;該表單提交的請(qǐng)求方式為 post 類型 --%>
<form action="${pageContext.request.contextPath}/user/pojoParam" method="post">
編號(hào):<input type="text" name="id"><br>
用戶名:<input type="text" name="username">
<input type="submit" value="對(duì)象類型參數(shù)">
</form>
創(chuàng)建 User 類
public class User {
private Integer id;
private String username;
// setter getter...
}
在 UserController 中添加方法
@RequestMapping("/pojoParam")
public String pojoParam(User user){
System.out.println(user);
return "success";
}
-
中文亂碼過(guò)濾器
當(dāng) post 請(qǐng)求時(shí)维费,數(shù)據(jù)會(huì)出現(xiàn)亂碼果元,可以在 web.xml 設(shè)置一個(gè)過(guò)濾器來(lái)進(jìn)行編碼的過(guò)濾促王。
<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>
-
獲取數(shù)組類型參數(shù)
Controller 中的業(yè)務(wù)方法數(shù)組名稱與請(qǐng)求參數(shù)的 name 一致,參數(shù)值會(huì)自動(dòng)映射匹配而晒。
requestParam.jsp
<form action="${pageContext.request.contextPath}/user/arrayParam" method="post">
編號(hào):<br>
<input type="checkbox" name="id" value="1">1<br>
<input type="checkbox" name="ids" value="2">2<br>
<input type="checkbox" name="ids" value="3">3<br>
<input type="checkbox" name="ids" value="4">4<br>
<input type="submit" value="數(shù)組類型參數(shù)">
</form>
在 UserController 中添加方法
@RequestMapping("/arrayParam")
public String arrayParam(Integer[] ids){
System.out.println(Arrays.toString(ids));
return "success";
}
-
獲取集合(復(fù)雜)類型參數(shù)
獲得集合參數(shù)時(shí)蝇狼,要將集合參數(shù)包裝到一個(gè) POJO 中才可以。
requestParam.jsp
<form action="${pageContext.request.contextPath}/user/queryParam" method="post">
搜索關(guān)鍵字:
<input type="text" name="keyword"><br>
user對(duì)象:
<input type="text" name="user.id" placeholder="編號(hào)">
<input type="text" name="user.username" placeholder="姓名"><br>
list集合:
元素1:
<input type="text" name="userList[0].id" placeholder="編號(hào)">
<input type="text" name="userList[0].username" placeholder="姓名">
元素2:
<input type="text" name="userList[1].id" placeholder="編號(hào)">
<input type="text" name="userList[1].username" placeholder="姓名"><br>
Map集合:
元素1:
<input type="text" name="userMap['u1'].id" placeholder="編號(hào)">
<input type="text" name="userMap['u1'].username" placeholder="姓名">
元素2:
<input type="text" name="userMap['u2'].id" placeholder="編號(hào)">
<input type="text" name="userMap['u2'].username" placeholder="姓名"><br>
<input type="submit" value="復(fù)雜類型">
</form>
創(chuàng)建 QueryVo 類
public class QueryVo {
private String keyword;
private User user;
private List<User> userList;
private Map<String, User> userMap;
// setter getter...
}
在 UserController 中添加方法
@RequestMapping("/queryParam")
public String queryParam(QueryVo queryVo){
System.out.println(queryVo);
return "success";
}
-
自定義類型轉(zhuǎn)換器
SpringMVC 默認(rèn)已經(jīng)提供了一些常用的類型轉(zhuǎn)換器倡怎。例如:客戶端提交的字符串轉(zhuǎn)換成 INT 型進(jìn)行參數(shù)設(shè)置迅耘,日期格式類型要求為:yyyy/MM/dd 不然的話會(huì)報(bào)錯(cuò)贱枣;對(duì)于特有的行為,SpringMVC 提供了自定義類型轉(zhuǎn)換器方便開(kāi)發(fā)者自定義處理颤专。
requestParam.jsp
<form action="${pageContext.request.contextPath}/user/converterParam" method="post">
生日:<input type="text" name="birthday">
<input type="submit" value="自定義類型轉(zhuǎn)換器">
</form>
配置自定義日期轉(zhuǎn)換 DateConverter
public class DateConverter implements Converter<String, Date> {
/**
* s 就是表單傳遞過(guò)來(lái)的請(qǐng)求參數(shù)纽哥,如 2012-12-12
*/
@Override
public Date convert(String s) {
// 將日期字符串轉(zhuǎn)換成日期對(duì)象,進(jìn)行返回
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = simpleDateFormat.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
spring-mvc.xml
<!-- 自定義類型轉(zhuǎn)換器配置 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.zm.converter.DateConverter"/>
</set>
</property>
</bean>
<!-- 處理器映射器-處理器適配器栖秕。進(jìn)行了功能的增強(qiáng):支持 json 的讀寫(xiě) -->
<mvc:annotation-driven conversion-service="conversionService"/>
在 UserController 中添加方法
@RequestMapping("/converterParam")
public String converterParam(Date birthday){
System.out.println(birthday);
return "success";
}
-
相關(guān)注解
@RequestParam
當(dāng)請(qǐng)求的參數(shù) name 名稱與 Controller 的業(yè)務(wù)方法參數(shù)名稱不一致時(shí)春塌,就需要通過(guò) @RequestParam 注解顯示的綁定
requestParam.jsp
<a href="${pageContext.request.contextPath}/user/findByPage?pageNo=2">
分頁(yè)查詢
</a>
在 UserController 中添加方法
/**
* name:匹配頁(yè)面?zhèn)鬟f參數(shù)的名稱
* defaultValue:設(shè)置參數(shù)的默認(rèn)值
* required:設(shè)置是否必須傳遞該參數(shù),默認(rèn)值為 true簇捍;如果設(shè)置了默認(rèn)值只壳,值自動(dòng)改為 false
*/
@RequestMapping("findByPage")
public String findByPage(
@RequestParam(name = "pageNo", defaultValue = "1", required = false) Integer pageNum,
@RequestParam(defaultValue = "5") Integer pageSize) {
System.out.println(pageNum);
System.out.println(pageSize);
return "success";
}
@RequestHeader
獲取請(qǐng)求頭的數(shù)據(jù)。
在 UserController 中添加方法
@RequestMapping("/requestHeader")
public String requestHead(@RequestHeader("cookie") String cookie){
System.out.println(cookie);
return "success";
}
@CookieValue
獲取 cookie 中的數(shù)據(jù)暑塑。
在 UserController 中添加方法
@RequestMapping("/cookieValue")
public String cookieValue(@CookieValue("JSESSIONID") String jSessionId){
System.out.println(jSessionId);
return "success";
}
-
獲取 Servlet 相關(guān) API
SpringMVC 支持使用原始 Servlet API 對(duì)象作為控制器方法的參數(shù)進(jìn)行注入吼句,常用的對(duì)象如下:
@RequestMapping("/servletAPI")
public String servletApi(HttpServletRequest request, HttpServletResponse response, HttpSession session){
System.out.println(request);
System.out.println(response);
System.out.println(session);
return "success";
}
SpringMVC 的響應(yīng)
-
SpringMVC 響應(yīng)方式介紹
頁(yè)面跳轉(zhuǎn):
- 返回字符串邏輯視圖
- void 原始 ServletAPI
- ModelAndView
返回?cái)?shù)據(jù):
- 直接返回字符串?dāng)?shù)據(jù)
- 將對(duì)象或集合轉(zhuǎn)為 json 返回
返回字符串邏輯視圖
直接返回字符串:此種方式會(huì)將返回的字符串與視圖解析器的前后綴拼接后跳轉(zhuǎn)到指定頁(yè)面
@RequestMapping("/returnString")
public String returnString() {
return "success";
}
void 原始 ServletAPI
可以通過(guò) request、response 對(duì)象實(shí)現(xiàn)響應(yīng)
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Index</title>
</head>
<body>
Hello ${username}
</body>
</html>
在 UserController 中添加方法
@RequestMapping("/returnVoid")
public void returnVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/* 直接返回?cái)?shù)據(jù) */
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("張三 ");
request.setAttribute("username", "zhangsan");
// 借助 request 對(duì)象完成請(qǐng)求轉(zhuǎn)發(fā)事格,一次請(qǐng)求
// request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request, response);
// request.getRequestDispatcher("/index.jsp").forward(request, response);
// 借助 response 對(duì)象完成重定向惕艳,兩次請(qǐng)求。WEB-INF - 安全目錄:不允許外部請(qǐng)求直接訪問(wèn)該目錄資源驹愚,只可以進(jìn)行服務(wù)器內(nèi)部轉(zhuǎn)發(fā)
// response.sendRedirect(request.getContextPath() + "/index.jsp");
}
轉(zhuǎn)發(fā)和重定向
企業(yè)開(kāi)發(fā)一般使用返回字符串邏輯視圖實(shí)現(xiàn)頁(yè)面的跳轉(zhuǎn)尔艇,這種方式其實(shí)就是請(qǐng)求轉(zhuǎn)發(fā);也可以寫(xiě)成:forward 轉(zhuǎn)發(fā)么鹤。如果用了 forward终娃,則路徑必須寫(xiě)成實(shí)際視圖 URL,不能寫(xiě)邏輯視圖蒸甜。它相當(dāng)于:
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response)
使用請(qǐng)求轉(zhuǎn)發(fā)棠耕,既可以轉(zhuǎn)發(fā)到 JSP,也可以轉(zhuǎn)發(fā)到其他的控制器方法柠新。
@RequestMapping("/forward")
public String forward(Model model){
// 在模型中設(shè)置一些值
model.addAttribute("username","zhangsan");
// 使用請(qǐng)求轉(zhuǎn)發(fā)窍荧,既可以轉(zhuǎn)發(fā)到 jsp,也可以轉(zhuǎn)發(fā)到其他的控制器方法
// return "forward:/product/findAll";
return "forward:/WEB-INF/pages/success.jsp";
}
Redirect 重定向:可以不寫(xiě)虛擬目錄,SpringMVC 框架會(huì)自動(dòng)拼接恨憎,并且將 Model 中的數(shù)據(jù)拼接到 URL 地址上蕊退;重定向的目標(biāo) JSP 頁(yè)面不能寫(xiě)在 WEB-INF 目錄中,否則無(wú)法找到憔恳。
@RequestMapping("/redirect")
public String redirect(Model model) {
// 底層使用的還是 request.setAttribute("username","lucky")瓤荔,
// 域范圍是一次請(qǐng)求,所以重定向后钥组,請(qǐng)求發(fā)生了變化输硝,請(qǐng)求域的值無(wú)法獲取
model.addAttribute("username", "lucky");
return "redirect:/index.jsp";
}
ModelAndView
方式一
在 Controller 中方法創(chuàng)建并返回 ModelAndView 對(duì)象,并且設(shè)置視圖名稱
/**
* model:模型:作用封裝存放數(shù)據(jù)
* View :視圖:用來(lái)展示數(shù)據(jù)
*/
@RequestMapping("/returnModelAndView")
public ModelAndView returnModelAndView(){
ModelAndView modelAndView = new ModelAndView();
// 設(shè)置模型數(shù)據(jù)
modelAndView.addObject("username","modelAndView 方式一");
// 設(shè)置視圖名稱程梦。視圖解析器解析 modelAndView 拼接前綴和后后綴
modelAndView.setViewName("success");
return modelAndView;
}
方式二
在 Controller 中方法形參上直接聲明 ModelAndView点把,無(wú)需在方法中自己創(chuàng)建橘荠,在方法中直接使用該對(duì)象設(shè)置視圖,同樣可以跳轉(zhuǎn)頁(yè)面
@RequestMapping("/returnModelAndView2")
public ModelAndView returnModelAndView2(ModelAndView modelAndView){
// 設(shè)置模型數(shù)據(jù)
modelAndView.addObject("username","modelAndView 方式二");
// 設(shè)置視圖名稱郎逃。視圖解析器解析 modelAndView 拼接前綴和后后綴
modelAndView.setViewName("success");
return modelAndView;
}
@SessionAttributes
如果在多個(gè)請(qǐng)求之間共用數(shù)據(jù)哥童,則可以在控制器類上標(biāo)注一個(gè) @SessionAttributes,配置需要在 session 中存放的數(shù)據(jù)范圍褒翰,SpringMVC 將存放在 model 中對(duì)應(yīng)的數(shù)據(jù)暫存到 HttpSession 中如蚜。
注意:@SessionAttributes 只能定義在類上
@Controller
@RequestMapping("/user") //一級(jí)訪問(wèn)目錄
@SessionAttributes("username") // 向 request 域中(model)中存入 key 為 username 時(shí),會(huì)同步到 session 域中
public class UserController {
...
@RequestMapping("/forward")
public String forward(Model model) {
// 在模型中設(shè)置一些值
model.addAttribute("username", "zhangsan");
// 使用請(qǐng)求轉(zhuǎn)發(fā)影暴,既可以轉(zhuǎn)發(fā)到 jsp,也可以轉(zhuǎn)發(fā)到其他的控制器方法
// return "forward:/product/findAll";
return "forward:/WEB-INF/pages/success.jsp";
}
...
@RequestMapping("/returnString")
public String returnString(){
return "success";
}
}
-
小結(jié)
頁(yè)面跳轉(zhuǎn)采用返回字符串邏輯視圖
forward 轉(zhuǎn)發(fā)
可以通過(guò)Model向request域中設(shè)置數(shù)據(jù)
redirect 重定向
直接寫(xiě)資源路徑即可错邦,虛擬目錄springMVC框架自動(dòng)完成拼接數(shù)據(jù)存儲(chǔ)到 request 域中
Model model
model.addAttribute("username", "子慕");
靜態(tài)資源訪問(wèn)的開(kāi)啟
requestParam.jsp
...
<%-- 引入 jquery.js --%>
<script src="${pageContext.request.contextPath}/js/jquery-3.5.1.js"></script>
...
當(dāng)有靜態(tài)資源需要加載時(shí),比如 jQuery 文件型宙,通過(guò)谷歌開(kāi)發(fā)者工具抓包發(fā)現(xiàn)撬呢,沒(méi)有加載到 jQuery 文件,原因是 SpringMVC 的前端控制器 DispatcherServlet 的 url-pattern 配置的是 /(默認(rèn)配置)妆兑,代表對(duì)所有的靜態(tài)資源都進(jìn)行處理操作魂拦,這樣就不會(huì)執(zhí)行 Tomcat 內(nèi)置的 DefaultServlet 處理,可以通過(guò)以下兩種方式在 spring-mvc.xml 指定放行靜態(tài)資源搁嗓。
方式一:放行指定的靜態(tài)資源
<!-- mapping:放行的映射路徑芯勘,location:靜態(tài)資源所在的目錄 -->
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
<mvc:resources mapping="/img/**" location="/img/"/>
方式二:放行全部的靜態(tài)資源
<!-- 在 springmvc 配置文件中開(kāi)啟 DefaultServlet 處理靜態(tài)資源 -->
<mvc:default-servlet-handler/>