1 前言
@RequestMapping 註解用於標註一個方法爲請求映射方法,springMVC 通過此註解將請求路徑與控制層中的方法進行匹配,用於響應請求。控制層(被 @Controller 標註的類)中,只有加了 @RequestMapping 註解的方法才參與請求路徑匹配。另外,@RequestMapping 也可以加在類上,作用等同於添加了一層命名空間。@RequestMapping 註解主要有以下屬性:
- value:設置待調用方法的請求名稱,支持 Ant 方式訪問路徑,即 *、?、** 三種通配符。
- method:常用的值有 GET(查詢)、POST(添加)、PUT(修改)、DELETE(刪除),用於設置請求方式,只有客戶端發送的請求方式和 method 值一致,才能處理請求。
- params:用來設置客戶端傳到服務器的參數。
在實驗之前,需要導入如下 jar 包:
筆者工作目錄如下:
2 案例分析
首先介紹下本文各節公共的文件,主要有 web.xml、applicationContext.xml、index.jsp、hello.jsp,不同的是 Test.java 文件,將在各節都介紹。
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<!-- 首頁網頁 -->
<welcome-file-list>
<welcome-file>/WEB-INF/view/index.jsp</welcome-file>
</welcome-file-list>
<!-- 配置核心(前端)控制器 DispatcherServlet -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- 加載IOC容器配置文件 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
applicationContext.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-4.0.xsd">
<!-- 掃描組件,將加@Controller註解的類作爲SpringMVC的控制層 -->
<context:component-scan base-package="com.test"></context:component-scan>
<!-- 配置視圖解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
hello.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>hello</title>
</head>
<body>
<h1>hello world!</h1>
</body>
</html>
2.1 @RequestMapping 加在類上
需要聲明的是,待訪問的方法上必須要加 @RequestMapping 註解,類上可加,也可以不加。若類上加了此註解,作用等同於添加了一層命名空間。
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>首頁</title>
</head>
<body>
<h1>
<a href="mvc/test">轉到 hello.jsp</a>
</h1>
</body>
</html>
注意:<a> 中請求跳轉到 “mvc/test” ,mvc 前面不要加“/”。
Test.java
package com.test;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping(value="mvc")
public class Test {
@RequestMapping(value="test")
public String test() {
System.out.println("SUCCESS");
return "hello";
}
}
@RequestMapping 中 value 的值前面可以加個“/”,地址欄輸入相同的網址,不影響運行結果;
@RequestMapping 中 value 值和方法名可以不同;
當 @RequestMapping 中只有 value 一個屬性時,可以省略 value,只顯示值。如下:
@RequestMapping("/mvc")
public class Test {
@RequestMapping("/test")
public String test123() {
System.out.println("SUCCESS");
return "hello";
}
}
運行結果:
2.2 Ant 方式訪問路徑
Ant 方式訪問路徑是指:@RequestMapping 註解的 value 屬性中可以使用如下3種通配符:
- *:任意多個字符。給 test() 方法標註@RequestMapping("*/test"),地址欄輸入http://localhost:8080/SpringMVC/abc/test 可以訪問 hello.jsp 頁面。
- ?:任意一個字符。給 test() 方法標註@RequestMapping("x?/test"),地址欄輸入http://localhost:8080/SpringMVC/x5/test 可以訪問 hello.jsp 頁面。
- **:任意多層目錄。給 test() 方法標註@RequestMapping("**/test"),地址欄輸入http://localhost:8080/SpringMVC/mn/x/test可以訪問 hello.jsp 頁面。
本文僅驗證第一個實驗,Test 類如下:
Test.java
package com.test;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class Test {
@RequestMapping("*/test")
public String testAnt() {
System.out.println("testAnt");
return "hello";
}
}
地址欄輸入:http://localhost:8080/SpringMVC/abc/test,顯示結果如下:
2.3 method 屬性
@RequestMapping 中 method 屬性用於設置請求方式,取值有 { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE },其中加粗的是常用的請求方式,作用如下:
- GET:查詢,如查詢成績
- POST:添加,如提交表單
- PUT:修改
- DELETE:刪除
mothod 屬性的設置方法如下:
@RequestMapping(value="test",method=RequestMethod.POST)
當設置了 method 屬性,除了請求地址要求和被調用的方法匹配外,請求方式也需要要求一致,如:提交表單後,請求調用的方法應該設置爲 POST,而不是 GET,否則會報錯:
HTTP Status 405 - Request method 'POST' not supported
2.4 params 屬性
@RequestMapping 中 params 屬性用於設置被調用方法需要傳遞的參數,主要有如下4中情況:
- params={"name"}:請求地址中必須包含 “name”
- params={"!name"}:請求地址中不能包含 “name”
- params={"name=admin"}:請求地址中必須包含 “name”,並且其取值必須爲 “admin”
- params={"name!=admin"}:請求地址中必須包含 “name”,並且其取值不能爲 “admin”
Test.java
package com.test;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class Test {
@RequestMapping(value="test",params={"name","age!=30"})
public String test456(String name, Integer age) {
System.out.println(name+"-"+age);
return "hello";
}
}
實驗一:在地址欄輸入http://localhost:8080/SpringMVC/test?name=admin&age=30
控制檯輸出:
五月 29, 2020 5:48:25 下午 org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver handleNoSuchRequestHandlingMethod
警告: No matching handler method found for servlet request: path '/test', method 'GET', parameters map['name' -> array<String>['admin'], 'age' -> array<String>['30']]
實驗二:在地址欄輸入http://localhost:8080/SpringMVC/test?name=admin&age=31
控制檯輸出:
admin-31
2.5 應用請求佔位符
應用請求佔位符和 params 屬性的功能類似,用於設置被調用方法需要傳遞的參數。
Test.java
package com.test;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class Test {
@RequestMapping("test/{name}/{age}")
public String test456(@PathVariable("name")String name1, @PathVariable("age")Integer age1) {
System.out.println(name1+"-"+age1);
return "hello";
}
}
在地址欄輸入http://localhost:8080/SpringMVC/test/admin/35
控制檯輸出:
admin-35