SpringMVC 學習(二)——使用 @RequestMapping 對映請求
•Spring MVC 使用 @RequestMapping 註解為控制器指定可 以處理哪些 URL 請求
•在控制器的類定義及方法定義處都可標注
@RequestMapping
–類定義處:提供初步的請求對映資訊。相對於 WEB 應用的根目錄
–方法處:提供進一步的細分對映資訊。相對於類定義處的 URL。若
類定義處未標注 @RequestMapping,則方法處標記的 URL 相對於
WEB 應用的根目錄
•DispatcherServlet 截獲請求後,就通過控制器上
@RequestMapping 提供的對映資訊確定請求所對應的處理 方法。
使用 @RequestMapping 對映請求示例
類定義處標記的
@RequestMapping 限定了處理 器類可以處理所有 URI 為 /hello 的請求,它相對於 WEB 容器部 署的根路徑
處理器類可以定義多個處理方法,處理來 自/hello 下的請求
對映請求引數、請求方法或請求頭
•@RequestMapping 除了可以使用請求 URL 對映請求外,
還可以使用請求方法、請求引數及請求頭對映
•@RequestMapping 的 value 、 method 、 params 及 heads 分別表示請求 URL、請求方法、請求引數及請求頭的對映條 件,他們之間是與的關系,聯合使用多個條件可讓請求對映 更加精確化。
•params 和 headers支援簡單的表達式:
–param1: 表示請求必須包含名為 param1 的請求引數
–!param1: 表示請求不能包含名為 param1 的請求引數
–param1 != value1: 表示請求包含名為 param1 的請求引數,但其值 不能為 value1
–{“param1=value1”,
對映請求引數、請求方法或請求頭
•Ant 風格資源地址支援 3 種匹配符:
–?:匹配檔名中的一個字元
–*:匹配檔名中的任意字元
–**:** 匹配多層路徑
•@RequestMapping 還支援 Ant 風格的 URL:
–/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
P707. RequestMapping_PathVariable註解
@PathVariable 對映 URL 綁定的佔位符
•帶佔位符的 URL 是 Spring3.0 新增的功能,該功能在
SpringMVC 向 REST 目標挺進發展過程中具有里程碑的 意義
•通過 @PathVariable 可以將 URL 中佔位符引數綁定到控 制器處理方法的入參中:URL 中的 {xxx} 佔位符可以通過
@PathVariable("xxx") 綁定到操作方法的入參中。
REST
•REST:即 Representational State Transfer。(資源)表現層狀態轉化。是目前 最流行的一種互聯網軟件架構。它結構清晰、符合標準、易於理解、擴展方便, 所以正得到越來越多網站的採用
•資源(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 用來刪除資源。
•示例:
–/order/1 HTTP GET :得到 id = 1 的 order
–/order/1 HTTP DELETE:刪除 id = 1的 order
–/order/1 HTTP PUT:更新id = 1的 order
–/order HTTP POST:新增 order
•HiddenHttpMethodFilter:瀏覽器 form 表單只支援 GET
與 POST 請求,而DELETE、PUT 等 method 並不支
持,Spring3.0 添加了一個過濾器,可以將這些請求轉換 為標準的 http 方法,使得支援 GET、POST、PUT 與
DELETE 請求。
@PathVariable 綁定 URL 佔位符到入參
•帶佔位符的 URL 是 Spring3.0 新增的功能,該功能在
SpringMVC 向 REST 目標挺進發展過程中具有里程碑的 意義
•通過 @PathVariable 可以將 URL 中佔位符引數綁定到控 制器處理方法的入參中:URL 中的 {xxx} 佔位符可以通過 @PathVariable("xxx") 綁定到操作方法的入參中。
程式碼示例:
helloWorld.java
package com.xuehj.springmvc.handler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @program: SpringMVC
* @description: TODO
* @author: Mr.Xue
* @create: 2018-12-24 09:36
**/
@Controller
@RequestMapping("/view")
public class HelloWorld {
/**
* 1. 使用 @RequestMapping 註解來對映請求的 URL
* 2. 返回值會通過檢視解析器解析為實際的物理檢視, 對於 InternalResourceViewResolver 檢視解析器,
* 會做如下的解析:通過 prefix + returnVal + 字尾 這樣的方式得到實際的物理檢視, 然會做轉發操作
* /WEB-INF/views/success.jsp
*
* @return
*/
@RequestMapping("/helloworld")
public String hello() {
System.out.println("hello world");
return "success.jsp";
}
/**
* 常用: 使用 method 屬性來指定請求方式
*/
@RequestMapping(value = "/testMethod", method = RequestMethod.POST)
public String testMethod() {
System.out.println("testMethod");
return "success.jsp";
}
/**
* 瞭解: 可以使用 params 和 headers 來更加精確的對映請求. params 和 headers 支援簡單的表示式.
*
* @return
*/
@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.jsp";
}
@RequestMapping("/testAntPath/*/abc")
public String testAntPath() {
System.out.println("testAntPath");
return "success.jsp";
}
/**
* @param id
* @return
* @PathVariable 可以來對映 URL 中的佔位符到目標方法的引數中.
*/
@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") int id) {
System.out.println("testPathVariable: " + id);
return "../success.jsp";
}
/**
* Rest 風格的 URL.
* 以 CRUD 為例:
* 新增: /order POST
* 修改: /order/1 PUT update?id=1
* 獲取: /order/1 GET get?id=1
* 刪除: /order/1 DELETE delete?id=1
* <p>
* 如何傳送 PUT 請求和 DELETE 請求呢 ?
* 1. 需要配置 HiddenHttpMethodFilter
* 2. 需要傳送 POST 請求
* 3. 需要在傳送 POST 請求時攜帶一個 name="_method" 的隱藏域, 值為 DELETE 或 PUT
* <p>
* 在 SpringMVC 的目標方法中如何得到 id 呢?
* 使用 @PathVariable 註解
*/
@RequestMapping(value = "/testRest/{id}", method = RequestMethod.GET)
public String testRest(@PathVariable Integer id) {
System.out.println("testRest GET: " + id);
return "../success.jsp";
}
@RequestMapping(value = "/testRest", method = RequestMethod.POST)
public String testRest() {
System.out.println("testRest POST");
return "success.jsp";
}
@RequestMapping(value = "/testRest/{id}", method = RequestMethod.DELETE)
public String testRestDelete(@PathVariable Integer id) {
System.out.println("testRest Delete: " + id);
return "../success.jsp";
}
@RequestMapping(value = "/testRest/{id}", method = RequestMethod.PUT)
public String testRestPut(@PathVariable Integer id) {
System.out.println("testRest Put: " + id);
return "../success.jsp";
}
}
success.jsp
<%--
Created by IntelliJ IDEA.
User: 薛恆傑
Date: 2018/12/24
Time: 9:39
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true"%>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
dispatcher-servlet.xml
<?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: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/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置自定掃描的包 -->
<context:component-scan base-package="com.xuehj.springmvc"/>
<!-- 配置檢視解析器: 如何把 handler 方法返回值解析為實際的物理檢視 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--<property name="prefix" value="/view/"/>-->
<!--<property name="suffix" value=".jsp"/>-->
<property name="prefix" value=""/>
<property name="suffix" value=""/>
</bean>
</beans>
web.xml
<?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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--
配置 org.springframework.web.filter.HiddenHttpMethodFilter: 可以把 POST 請求轉為 DELETE 或 PUT 請求
-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置 DispatcherServlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置 DispatcherServlet 的一個初始化引數: 配置 SpringMVC 配置檔案的位置和名稱 -->
<!--
實際上也可以不通過 contextConfigLocation 來配置 SpringMVC 的配置檔案, 而使用預設的.
預設的配置檔案為: /WEB-INF/<servlet-name>-servlet.xml
-->
<!--
<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>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
index.jsp
<%--
Created by IntelliJ IDEA.
User: 薛恆傑
Date: 2018/12/24
Time: 9:21
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<a href="view/helloworld">Hello world</a>
<br><br>
<a href="view/testMethod">testMethod</a>
<br><br>
<form method="post" action="${pageContext.request.contextPath}/view/testMethod">
<input type="submit" value="提交"/>
</form>
<br><br>
<a href="view/testParamsAndHeaders">Test ParamsAndHeaders</a>
<br><br>
<a href="view/testAntPath/ddd/abc">Test AntPath</a>
<br><br>
<a href="view/testPathVariable/1">Test PathVariable</a>
<br><br>
<a href="view/testRest/1">Test Rest Get</a>
<br><br>
<form action="view/testRest" method="post">
<input type="submit" value="TestRest POST"/>
</form>
<br><br>
<form action="view/testRest/1" method="post">
<input type="hidden" name="_method" value="DELETE"/>
<input type="submit" value="TestRest DELETE"/>
</form>
<br><br>
<form action="view/testRest/1" method="post">
<input type="hidden" name="_method" value="PUT"/>
<input type="submit" value="TestRest PUT"/>
</form>
</body>
</html>