什麼是SpringMVC?
SpringMVC:是一個模型-試圖-控制器(MVC)的Web框架,他提供了MVC架構和用於開發靈活和鬆散耦合的Web應用程序的組件,MVC模式導致應用程序的不同方面(輸入邏輯,業務邏輯和UI邏輯)分離。
- 模型(Model):封裝了應用程序數據,一般由POJO類組成
- 視圖(View):負責渲染模型數據,一般來說它生產客戶端瀏覽器可以解釋HTML輸出
- 控制器(Controller):負責處理用戶請求並構建適當的模型,並將其傳遞給視圖進行渲染
SpringMVC的簡單開發步驟
我們依然使用maven來創建一個web項目,然後進行配置。
首先,我們需要在pom.xml的dependency座標導入SpringMVC相關的依賴,這裏導入的比較多,有備無患,開發中可以按照需要導入:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
然後我們去配置web.xml:
<!--配置生成啓動時需要構建IOC容器的Servlet,需要springmvc的配置文件,Servlet的對象默認構造時間是,第一個訪問該servlet時才構建該Servlet的對象-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--設置當前Servlet的初始化參數,如果不設置,默認名稱爲servlet-name-servlet.xml,且該文件必須在WEB-INF目錄下-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--設置當前Servlet的初始化參數,一般爲1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--在Web工廠中註冊的dispatcherServlet需要攔截所有的請求資源-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
解釋一下,SpringMVC就相當於做了Servlet做的事情,它給我們提供了一個DispatcherServlet類來構建Spring IOC容器
然後在自帶的index.jsp下配置一個超鏈接:
<a href="/helloWorld">Test Hello World</a>
在java目錄下創建一個HelloWorld類,來處理index.jsp下的超鏈接
@Controller //用來指示該類充當控制器的角色
public class HelloWorld {
@RequestMapping("/hello")
public String helloWorld(ModelMap modelMap) {
//ModelMap用來設置一個key-value對,key用於jsp來讀取後面的value。
modelMap.addAttribute("message", "hello");
return "hello";
}
}
接下來,由於我們return的是hello,所以在WEB-INF下創建一個views,用來放我們的jsp頁面,我們在該目錄下創建一個hello.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Hello</title>
</head>
<body>
利用EL表達式來讀取Controller方法的信息
<h1>${message}</h1>
</body>
</html>
可以看到我們用的EL表達式去讀取controller裏的message,讀取到的其實就是"hello"。
最後,我們去配置springmvc.xml裏的視圖解析器:
<bean id="resolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
完整的springmvc.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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!--配置請求的默認處理的Servlet,它是web容器提供的。
default-servlet-name屬性:是指默認處理請求的servlet註冊到web容器中定義的名稱
使用了此標籤就必須添加<mvc:annotation-driven />這個標籤
從默認的請求裏面找,如果有就不經過SpringMVC了-->
<mvc:default-servlet-handler />
<!--有一點要說的是,比如使用context,這個傻屌xml不會自己寫schemaLocation,只能自己補上,如果寫不全則會導致無法運行-->
<!--配置視圖解析器
概念解釋:
1.該xml將用於創建定義的bean,它會覆蓋在全局範圍中使用相同名稱定義的任何bean的定義
2.<context:component-scan base-package="com.hty" /> 用於激活SpringMVC註釋掃描功能,就能掃描到例如@Controller和@ResultMapping等註解
3.InternalResourceViewResolver類則用於定義用於解析視圖名稱的規則。例如根據上面定義的規則,hello的邏輯視圖將委託給位於
/WEB-INF/views/hello.jsp這個視圖來實現
-->
<context:component-scan base-package="com.hty" />
<context:annotation-config />
<mvc:annotation-driven />
<bean id="resolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<!--使用該標記來映射靜態頁面。映射的屬性值必須是指定http請求的URL模式的Ant模式。location屬性必須指定一個或多個有效地資源目錄配置,
其中包含靜態頁面,包括圖片,樣式表,JS和其他靜態內容。可以用逗號分隔的值列表來指定多個資源位置
-->
<!--<mvc:resources mapping="WEB-INF/views/**" location="/views/" />-->
<!--文件上傳所用的bean-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
<!--處理錯誤所用的bean-->
<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
<property name="basename" value="messages" />
</bean>
</beans>
至此,前期準備工作算是ojbk了,我們來請求一下,跑一下試試:
最後講一下,SpringMVC是圍繞着DispatcherServlet設計的,DispatcherServlet傳入HTTP請求來發生事件的順序爲:
- 在接受到HTTP請求後,DispatcherServlet會查詢HandlerMapping以調用響應的Controller
- Controller接受請求並根據使用的GET或POST方法調用相應的服務方法。服務方法將基於定義的業務邏輯設置模型數據,並將視圖名稱返回給DispatcherServlet
- DispatcherServlet將從ViewResolver獲取請求的定義視圖
- 當視圖完成,DispatcherServlet將模型數據傳遞到最終的視圖,並在瀏覽器上呈現
轉發與重定向?
一般Controller裏面的@RequestMapping方法返回值都爲一個頁面,我們可以在裏面利用此來進行轉發與重定向。
我們寫一個類Redirect
package com.hty.jingtaiyemian;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @program: springmvc
* @author: Semineces
* @create: 2020-02-09 15:33
*/
@Controller
public class Redirect {
@RequestMapping(value = "/index", method = RequestMethod.GET)
public String index() {
return "index";
}
@RequestMapping(value = "/redirect", method = RequestMethod.GET)
public String redirect() {
//重定向到下面的finalPage
return "redirect:finalPage";
}
@RequestMapping(value = "/finalPage", method = RequestMethod.GET)
public String finalPage() {
return "final";
}
@RequestMapping(value = "/forward", method = RequestMethod.GET)
private String staticPage() {
return "forward:/WEB-INF/views/forward.jsp";
}
}
然後我們在view下創建三個jsp文件,index.jsp、final.jsp、forward.jsp:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>Spring Landing Page</title>
</head>
<body>
<h2>Spring頁面重定向與頁面轉發</h2>
<!--訪問redirect,而卻要跳到finalPage,這就是我們的目標-->
<form:form method="GET" action="${pageContext.request.contextPath}/redirect" >
<table>
<tr>
<td><input type="submit" value="頁面重定向" /></td>
</tr>
</table>
</form:form>
<form:form method="GET" action="${pageContext.request.contextPath}/forward">
<table>
<tr>
<td>
<input type="submit" value="頁面轉發" />
</td>
</tr>
</table>
</form:form>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SpringMVC重定向頁面</title>
</head>
<body>
<h2>重定向頁面。。。</h2>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>SpringMVC轉發頁面</title>
</head>
<body>
<h2>轉發的頁面</h2>
</body>
</html>
我們啓動服務器,訪問index:
我們試試重定向,可以看出,我們原本是要訪問/redirect,可最後的url後面是/finalPage:
在試試轉發,還是forward,內容也設forward.jsp裏的內容: