后端必會的 Spring MVC 核心類和注解
GitHub:https://github.com/nateshao/ssm/tree/master/107-springmvc-demo
1. DispatcherServlet
“DispatcherServlet的全名是org.springframework.web.servlet.DispatcherServlet,它在程序中充當(dāng)著前端控制器的角色。在使用時,只需將其配置在項目的web.xml文件中,其配置代碼如下:
- <servlet>
- <!-- 如果沒有通過< init-param >元素配置,則應(yīng)用程序會默認(rèn)去WEB-INF目錄下尋找以servletName-servlet.xml方式命名的配置文件,這里的servletName指下面的springmvc -->
- <servlet-name>springmvc</servlet-name>
- <servlet-class>
- org.springframework.web.servlet.DispatcherServlet
- </servlet-class>
- <!-- 如果< init-param >元素存在并且通過其子元素配置了Spring MVC配置文件的路徑,則應(yīng)用程序在啟動時會加載配置路徑下的配置文件 -->
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:springmvc-config.xml</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>springmvc</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
2. @Controller注解類型
“org.springframework.stereotype.Controller注解類型用于指示Spring類的實例是一個控制器,其注解形式為@Controller。該注解在使用時不需要再實現(xiàn)Controller接口,只需要將@Controller注解加入到控制器類上,然后通過Spring的掃描機制找到標(biāo)注了該注解的控制器即可。
@Controller注解在控制器類中的使用示例如下:
- @Controller
- public class HelloController {
- @RequestMapping("hello")
- public String hello(){
- return "hello";
- }
- }
為了保證Spring能夠找到控制器類,還需要在Spring MVC的配置文件中添加相應(yīng)的掃描配置信息,一個完整的配置文件示例如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- <!-- 引入context信息 -->
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-4.3.xsd">
- <!-- 指定需要掃描的 -->
- <context:component-scan base-package="com.nateshao.controller" />
- </beans>
注意:使用注解方式時,程序的運行需要依賴Spring的AOP包,因此需要向lib目錄中添加spring-aop-4.3.6.RELEASE.jar,否則程序運行時會報錯!
3. @RequestMapping注解類型
“Spring通過@Controller注解找到相應(yīng)的控制器類后,還需要知道控制器內(nèi)部對每一個請求是如何處理的,這就需要使用@RequestMapping注解類型,它用于映射一個請求或一個方法。使用時,可以標(biāo)注在一個方法或一個類上。
1. 標(biāo)注在方法上: 作為請求處理方法在程序接收到對應(yīng)的URL請求時被調(diào)用:
- @Controller
- public class FirstController{
- @RequestMapping(value="/firstController")
- public ModelAndView handleRequest(HttpServletRequest request,
- HttpServletResponse response) {
- ...
- return mav;
2. 標(biāo)注在類上: 該類中的所有方法都將映射為相對于類級別的請求,表示該控制器所處理的所有請求都被映射到value屬性值所指定的路徑下。
- @Controller
- @RequestMapping(value="/hello")
- public class FirstController{
- @RequestMapping(value="/firstController")
- public ModelAndView handleRequest(HttpServletRequest request,
- HttpServletResponse response) {
- ...
- return mav;
- }
- }
由于在類上添加了@RequestMapping注解,并且其value屬性值為“/hello”,所以上述代碼方法的請求路徑將變?yōu)椋篽ttp://localhost:8080/106-springmvc-hello/hello
@RequestMapping注解除了可以指定value屬性外,還可以指定其他一些屬性,如下表所示。
表中所有屬性都是可選的,但其默認(rèn)屬性是value。當(dāng)value是其唯一屬性時,可以省略屬性名。例如,下面兩種標(biāo)注的含義相同:
@RequestMapping(value="/firstController")
@RequestMapping("/firstController")
組合注解
“Spring框架的4.3版本中,引入了新的組合注解,來幫助簡化常用的HTTP方法的映射,并更好的表達(dá)被注解方法的語義。
Spring的4.3版本中的組合注解及其描述如下所示:
- @GetMapping:匹配GET方式的請求;
- @PostMapping:匹配POST方式的請求;
- @PutMapping:匹配PUT方式的請求;
- @DeleteMapping:匹配DELETE方式的請求;
- @PatchMapping:匹配PATCH方式的請求。
以@GetMapping為例,該組合注解是@RequestMapping(method = RequestMethod.GET)的縮寫,它會將HTTP GET請求映射到特定的處理方法上。
在實際開發(fā)中,傳統(tǒng)的@RequestMapping注解使用方式如下:
- @RequestMapping(value="/user/{id}",method=RequestMethod.GET)
- public String selectUserById(String id){
- ...
- }
使用@GetMapping注解后的簡化代碼如下:
- @GetMapping(value="/user/{id}")
- public String selectUserById(String id){
- ...
- }
請求處理方法的參數(shù)和返回類型
在控制器類中,每一個請求處理方法都可以有多個不同類型的參數(shù),以及一個多種類型的返回結(jié)果。在請求處理方法中,可以出現(xiàn)的參數(shù)類型如下:
- javax.servlet.ServletRequest / javax.servlet.http.HttpServletRequest
- javax.servlet.ServletResponse / javax.servlet.http.HttpServletResponse
- javax.servlet.http.HttpSession
- org.springframework.web.context.request.WebRequest或
- org.springframework.web.context.request.NativeWebRequest
- java.util.Locale
- java.util.TimeZone (Java 6+) / java.time.ZoneId (on Java 8)
- java.io.InputStream / java.io.Reader
- java.io.OutputStream / java.io.Writer
- org.springframework.http.HttpMethod
- java.security.Principal
- @PathVariable、@MatrixVariable、@RequestParam、@RequestHeader、@RequestBody、@RequestPart、@SessionAttribute、@RequestAttribute注解
- HttpEntity<?>
- java.util.Map / org.springframework.ui.Model /org.springframework.ui.ModelMap
- org.springframework.web.servlet.mvc.support.RedirectAttributes
- org.springframework.validation.Errors /org.springframework.validation.BindingResult
- org.springframework.web.bind.support.SessionStatus
- org.springframework.web.util.UriComponentsBuilder
該類型不是一個Servlet API類型,而是一個包含了Map對象的Spring MVC類型。如果方法中添加了Model參數(shù),則每次調(diào)用該請求處理方法時,Spring MVC都會創(chuàng)建Model對象,并將其作為參數(shù)傳遞給方法
請求處理方法的返回類型
Spring MVC所支持的常見方法返回類型如下:
由于ModelAndView類型未能實現(xiàn)數(shù)據(jù)與視圖之間的解耦,所以在企業(yè)開發(fā)時,方法的返回類型通常都會使用String。
既然String類型的返回值不能攜帶數(shù)據(jù),那么在方法中是如何將數(shù)據(jù)帶入視圖頁面的呢?
通過Model參數(shù)類型,即可添加需要在視圖中顯示的屬性,其示例代碼如下:
- @RequestMapping(value="/firstController")
- public String handleRequest(HttpServletRequest request,
- HttpServletResponse response, Model model) {
- model.addAttribute("msg", "這是我的第一個Spring MVC程序");
- return "/WEB-INF/jsp/first.jsp";
- }
String類型除了可以返回上述代碼中的視圖頁面外,還可以進行重定向與請求轉(zhuǎn)發(fā),具體方式如下:
1. redirect 重定向。例如,在修改用戶信息操作后,將請求重定向到用戶查詢方法的實現(xiàn)代碼如下:
- @RequestMapping(value="/update")
- public String update(HttpServletRequest request,HttpServletResponse response, Model model){
- ...
- return "redirect:queryUser";
- }
2. forward 請求轉(zhuǎn)發(fā)。例如,用戶執(zhí)行修改操作時,轉(zhuǎn)發(fā)到用戶修改頁面的實現(xiàn)代碼如下:
- @RequestMapping(value="/toEdit")
- public String update(HttpServletRequest request,HttpServletResponse response, Model model){
- ...
- return "forward:editUser";
- }
4. ViewResolver(視圖解析器)
Spring MVC中的視圖解析器負(fù)責(zé)解析視圖??梢酝ㄟ^在配置文件中定義一個ViewResolver來配置視圖解析器,其配置示例如下:
- <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/WEB-INF/jsp/" />
- <property name="suffix" value=".jsp" />
- </bean>
在上述代碼中,定義了一個視圖解析器,并設(shè)置了視圖的前綴和后綴屬性。這樣設(shè)置后,方法中所定義的view路徑將可以簡化。例如,入門案例中的邏輯視圖名只需設(shè)置為“first”,而不再需要設(shè)置為“/WEB-INF/jsp/first.jsp”,在訪問時視圖解析器會自動的增加前綴和后綴。
5. 基于注解的Spring MVC應(yīng)用
代碼附上!!
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>
- <servlet>
- <servlet-name>dispatcher</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>dispatcher</servlet-name>
- <!-- <url-pattern>*.form</url-pattern>-->
- <url-pattern>/</url-pattern>
- </servlet-mapping>
- </web-app>
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"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context
- https://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/mvc
- https://www.springframework.org/schema/mvc/spring-mvc.xsd">
- <context:component-scan base-package="com.nateshao.controller"/>
- <mvc:default-servlet-handler/>
- <mvc:annotation-driven/>
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
- <property name="prefix" value="/WEB-INF/jsp/"/>
- <property name="suffix" value=".jsp"/>
- </bean>
- </beans>
hello.jsp
- <%--
- Created by IntelliJ IDEA.
- User: 邵桐杰
- Date: 2021/10/16
- Time: 21:34
- 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>
- ${msg}
- </body>
- </html>
HelloController.java
- package com.nateshao.controller;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.RequestMapping;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- /**
- * @date Created by 邵桐杰 on 2021/10/16 21:37
- * @微信公眾號 程序員千羽
- * @個人網(wǎng)站 www.nateshao.cn
- * @博客 https://nateshao.gitee.io
- * @GitHub https://github.com/nateshao
- * @Gitee https://gitee.com/nateshao
- * Description:
- */
- @Controller
- public class HelloController {
- @RequestMapping("/hello")
- public String handleRequest(HttpServletRequest request,
- HttpServletResponse response, Model model) throws Exception {
- // 向模型對象中添加數(shù)據(jù)
- model.addAttribute("msg", "這是我的第一個Spring MVC程序");
- // 返回視圖頁面
- return "hello";
- }
- }
總結(jié)
這一篇文章主要對Spring MVC的核心類及其相關(guān)注解的使用進行了詳細(xì)的講解。
- 首先介紹了DispatcherServlet的作用和配置;
- 然后介紹了@Controller以及@RequestMapping注解類型的相關(guān)知識;
- 最后講解了視圖解析器的定義和配置,并通過一個應(yīng)用案例,將所講解的內(nèi)容進行了一個全面總結(jié)。
通過本章的學(xué)習(xí),我相信我們能夠了解Spring MVC核心類的作用,并掌握Spring MVC常用注解的使用。