SpringMVC架構是基于Spring架構,可以讓我們更為友善的進行Web的開發,實作前後端分離
思路和原理
我們之前仿照SpringMVC定義了一個自定義MVC架構,兩者的思路其實都是一樣的。
建議結合兩篇文章進行學習
JSP學習筆記(6)—— 自定義MVC架構
首先,提供一個前置攔截器(DispatchServlet),攔截url請求,之後,根據url請求,跳轉到Controller層,執行操作,之後再傳回資料
入門
我的demo是使用了maven架構
1.建立maven項目
按照下圖進行配置

2.添加依賴
修改pom.xml,添加依賴
剛開始的時候,使用的是最新版本(5.x.x),然後發現有個奇怪的錯誤,折騰了許久找不到方法,于是便用了4.x.x版本的,果然沒有出現問題了,果然是新版本都不好用。。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--日志-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.9.release</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.9.release</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.9.release</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.9.release</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.9.release</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.9.release</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.9.release</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.9.release</version>
</dependency>
<!--AOP-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.9.release</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>RELEASE</version>
</dependency>
<!-- springmvc依賴的json庫(如果使用@responsebody注解傳回json資料) -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!-- jstl 1.2.5 version libarary -->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-spec</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
</dependency>
<!-- oracle driver -->
<dependency>
<groupId>com.github.noraui</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
</dependency>
<!-- mybatis orm架構 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!-- spring整合mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
<!-- 檔案上傳與下載下傳 -->
<!--
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
-->
3.項目結構優化
由于是根據maven模闆建立的項目,是以項目結構還需要添加一些檔案夾
在main檔案夾下建立java檔案夾
把java檔案夾設定為source directory
在java檔案夾下建立自己的包名,然後建立一個controller檔案夾和model檔案夾,順便也建立一個resources的檔案夾,和上面同樣的步驟,設定為resources directory
除此之外,還需要在webapp檔案夾下建立一個views檔案夾
4.設定Tomcat配置
我這裡是設定好了,沒有設定的話,是沒有下拉菜單的,但是有個add configuration的選項
選擇tomcat的設定,選擇local,如果沒有Tomcat的選項,可以點選選項最下面的show more
點選之後,添加構造物
選擇那個exploded的選項
設定url
之後開始運作Web程式,就可以通過通路
http://localhost:8080/springmvcdemo
來通路Web項目的首頁
5.建立springmvc配置檔案
springmvc配置檔案和之前的spring檔案一樣,都是進行相關的bean的配置,這裡由于是資源檔案,是以按照規則我們放入resources檔案夾中
springmvc-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 對web包中的所有類進行掃描,以完成Bean建立和自動依賴注入的功能-->
<!-- 把标記了controller和requestmapping注解的類和方法進行儲存,之後通過反射調用 -->
<context:component-scan base-package="com.wan.controller"/>
<!--支援spring3.0+ 新的mvc注解,不加有些注解功能不行,如json轉換的@ResponseBody
<context:annotation-config/>
将隐式地向 Spring 容器注冊
1. AutowiredAnnotationBeanPostProcessor 解決資料或元件自動裝配
2. CommonAnnotationBeanPostProcessor 解決相容JSR250規範的注解:@Resource,@PostConstruct,...
3. PersistenceAnnotationBeanPostProcessor 解決持久化注解處理
4. RequiredAnnotationBeanPostProcessor
這 4 個 BeanPostProcessor。
enable-matrix-variables="true": 開啟矩陣變量擷取資料的特性
-->
<mvc:annotation-driven enable-matrix-variables="true">
<mvc:async-support default-timeout="10"/><!--子元素可指定異步攔截器-->
</mvc:annotation-driven>
<!-- 配置*.js,*.css,*.jpg,*.html等的請不由DispatcherServlet處理,而直接交tomcat服務的預設Servlet來處理,
不同的伺服器其預設Servlet的名字是不同,但tomcat預設Servlet的名字叫“default”
-->
<mvc:default-servlet-handler/>
<!--對模型視圖名稱的解析,即在模型視圖名稱添加前字尾
UserController.login(){
return "success"; //spring mvc 解析為一個對應的jsp(視圖)/views/success.jsp
}
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/views/" p:suffix=".jsp">
<!-- /views/[login].jsp -->
<!-- 與p:prefix, p:suffix 等價
<property name="prefix" value="/views/" />
<property name="suffix" value=".jsp" />
-->
<!-- 如果使用jstl的話,配置下面的屬性 -->
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
</bean>
</beans>
配置中有個bean類,是配置視圖解析器(也就是最後的那個bean标簽),我們使用的是
InternalResourceViewResolver
此解析器會把請求處理類(controller類)處理方法的傳回值按照“字首+方法傳回值+字尾”的格式進行加工,并把加工後的傳回值作為路徑進行跳轉
除此之外,還有其他的解析器,下面會進行補充說明
6.配置web.xml檔案
由于我們使用的maven的模闆建立的web項目,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">
<display-name>SpringMVC Demo</display-name>
<!-- springmvc 核心控制器,将springMVC整合到項目裡-->
<servlet>
<servlet-name>springmvc-DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 配置spring mvc的元件:掃描controller, view resovle -->
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
<!-- 伺服器啟動時加載順序 -->
<load-on-startup>1</load-on-startup>
<!-- 異步請求處理支援 -->
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>springmvc-DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
7.測試
我們用一個簡單的例子去了解springmvc的使用方式
我們編寫一個controller類,用來模拟實作登入操作,登入成功,跳轉到登入成功的頁面
success.jsp
UserController.java
package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author StarsOne
* @date Create in 2019/9/28 0028 14:27
* @description
*/
@Controller
public class UserController {
@RequestMapping("/user/login")
public String login() {
//這裡的傳回,之後會加上字首和字尾
//相當于頁面跳轉到 views/success.jsp 頁面
return "success";
}
}
success.jsp
中,隻有一個簡單的“登入成功”文字
index.jsp中,有個連結,請求url為
user/login
<a href="user/login">登入</a>
之後就是可以跳轉到了頁面
PS:上面方法傳回了一個success,,會被自動加入字首和字尾,注意,這裡是進行的請求轉發
除此之外,我們還可以加上
forward
或
redirect
字首來進行請求轉發或重定向
但是,如果使用這兩種字首,之後視圖解析器就不會自動添加字首和字尾了。是以,我們得指定具體跳轉的url位址。
@RequestMapping("/user/login")
public String login() {
//請求轉發
return "forward:/views/success.jsp";
}
@RequestMapping("/user/login")
public String login() {
//重定向
return "redirect:/views/success.jsp";
}
RequestMapping注解
進階使用
springmvc架構中的RequestMapping注解不像我們之前自定義MVC架構的注解那樣簡單,它的還可以标注一個類
例如:
package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author StarsOne
* @date Create in 2019/9/28 0028 14:27
* @description
*/
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public String login() {
//這裡的傳回,相當于頁面跳轉到 views/success.jsp 頁面
return "success";
}
}
我們連結上的url請求就是
/user/login
,而不能使用
login
屬性說明及使用
屬性 | 說明 |
---|---|
value | 指定請求的實際url位址,是預設屬性,如@RequestMapping("/login") 相當于@RequestMapping(value="/login" |
method | 指定請求的方法,post或get |
params | 規定請求中的參數必須滿足一定的條件 |
header | 規定請求中的請求頭(header)必須滿足一定的條件 |
1.method
package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author StarsOne
* @date Create in 2019/9/28 0028 14:27
* @description
*/
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login",method="RequestMethod.POST")
public String login() {
//這裡的傳回,相當于頁面跳轉到 views/success.jsp 頁面
return "success";
}
}
之後如果請求不是post方式,就會出現405錯誤
2.params
使用此屬性可以對請求的參數進行限制
例子:
package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author StarsOne
* @date Create in 2019/9/28 0028 14:27
* @description
*/
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login",params={"name","age!=23"})
public String login() {
//這裡的傳回,相當于頁面跳轉到 views/success.jsp 頁面
return "success";
}
}
上面的例子限制的url的請求參數必須要包含有name和age,且age不能等于23,如果不滿足條件,就會發生404錯誤
如:
<!-- 滿足條件的url請求 -->
<a href="user/login?name=zhang&age=21">登入</a>
params中可以接收以下表達式
表達式 | |
---|---|
paramName | url請求必須包含paramName此參數名 |
!paramName | url請求不能包含paramName此參數名 |
paramName!=xx | url請求必須包含paramName此參數名,且此參數數值不等于xx |
header比較少用,這裡就不補充了
獲得請求url參數值
獲得url請求的參數值,我們可以使用RequestParam注解
使用此注解,可以把url請求參數的數值指派給方法參數
下面是@RequestParam注解的常用屬性說明
請求攜帶參數的參數名 | |
required | 辨別請求url參數是必須存在某個具體的參數,true(預設):必須存在,不存在則會發生異常;false:不存在 |
defaultValue | 給方法參數賦一個預設值,如果請求url不存在此參數,則使用預設值 |
package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author StarsOne
* @date Create in 2019/9/28 0028 14:27
* @description
*/
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public String login(@RequestParam(value="username") String name) {
//這裡的傳回,相當于頁面跳轉到 views/success.jsp 頁面
return "success";
}
}
請求url為
user/login?username=zhang
,之後便會把此請求參數指派給方法參數
name
和我們自定義mvc架構一樣,springmvc架構中,我們也可以直接使用實體類、session、request、response作為方法的參數
@RequestMapping("/user/login")
public login(Student student){
...
}
@RequestMapping("/user/login")
public login(HttpServletRequest request,HttpServletResponse response,HttpSession session){
...
}
與
RequestParam
類似的還有這兩個
RequestHeader
和
CookieValue
這兩個注解我現在沒怎麼用到,暫時了解一下,不作補充
- RequestHeader注解,主要是用來獲得請求頭的資料
- CookieValee注解,主要是用來獲得一個cookieValue
傳回json資料
我們使用
@ResponseBody
,方法傳回實體類或者集合的時候,springmvc就會自動幫我們轉為json資料
使用之前需要導入這兩個jar,
jackson-core.jar
jackson-databind.jar
,之前的依賴已經包含下面這兩個jar了
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.3</version>
</dependency>
package com.wan.controller;
import com.wan.model.Teacher;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author StarsOne
* @date Create in 2019/9/28 0028 14:27
* @description
*/
@Controller
@RequestMapping("/user")
public class UserController {
@ResponseBody
@RequestMapping("/login")
public Teacher login() {
return new Teacher("001", "張三");
}
}
之後在jsp頁面中使用ajax異步請求
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type='text/javascript'>
function getData() {
$.getJSON("user/login", function(json){
console.log(json);
});
}
</script>
</head>
<body>
<button onclick="getData()">登入</button>
</body>
</html>
就可以在控制台看到列印出來的json資料
處理Model資料
SpringMVC中,M其實就是代表着Model(模型),也就是相當于資料
假設我們要從資料查詢資料:先從頁面(View)發送url請求,然後控制器(Controller)通過Service/Dao從資料庫中獲得了資料(Model),并把資料進行處理,使得資料能夠傳回頁面(View)并顯示。
如果是異步請求的話,我們可以傳回一個json資料到頁面,如果不是的話,我們就得把資料存放在request或session的作用域裡,之後由頁面(View)從作用域中取出資料并顯示
SpringMVC提供了四種方法來處理那些需要從作用域中取出資料顯示的視圖
- ModelAndView
- Map、ModelMap和Model
- @SessionAttributes
- @ModelAttribute
1.ModelAndView
此類一般用來作方法的傳回值來實作傳回一個帶資料的頁面(View)
package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author StarsOne
* @date Create in 2019/9/28 0028 14:27
* @description
*/
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public ModelAndView login() {
String view = "success";
ModelAndView mav = new ModelAndView(view);
Teacher teacher = new Teacher("001","張三");
//相當于request.addAttribute("teacher",teacher)
mav.addObject("teacher",teacher);
return mav;
}
}
success.jsp中取出資料并顯示
<body>
${requestScope.student.tno}
</body>
上面的例子和之前一樣,還是會加上字首和字尾,得到
views/success.jsp
2.Map、ModelMap和Model
Map、ModelMap和Model一般使用作為方法的參數,之後,通過put方法往裡面存入資料
package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author StarsOne
* @date Create in 2019/9/28 0028 14:27
* @description
*/
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/login")
public String login(Map<String,Object> map) {
String view = "success";
Teacher teacher = new Teacher("001","張三");
//相當于request.addAttribute("teacher",teacher)
map.put("teacher",teacher);
return "success";
}
}
ModelMap和Map的使用方法一樣
還可以使用Model
@RequestMapping("/login")
public String login(Model model) {
String view = "success";
Teacher teacher = new Teacher("001","張三");
//相當于request.addAttribute("teacher",teacher)
model.addAttribute("teacher",teacher);
return "success";
}
Model類還可以使用添加一個map資料,addAllAttribute(Map<String,?> map)
3.@SessionAttributes
前面的兩個方法,都是放入到request的作用域裡,如果我們想放入session作用域,可以使用@SessionAttributes注解,一般标注在類上
@SessionAttributes可以将指定的對象加入到session範圍,也可以将某個類型的對象加入到session中
下面的例子,指定了key為teacher的對象,添加到了session作用域
package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author StarsOne
* @date Create in 2019/9/28 0028 14:27
* @description
*/
@Controller
@RequestMapping("/user")
@SessionAttributes(value="teacher")
public class UserController {
@RequestMapping("/login")
public String login(Map<String,Object> map) {
String view = "success";
Teacher teacher = new Teacher("001","張三");
//在添加到request作用域,同時也添加了session作用域
map.put("teacher",teacher);
return "success";
}
}
把Teacher類型的對象添加到session作用域中
package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author StarsOne
* @date Create in 2019/9/28 0028 14:27
* @description
*/
@Controller
@RequestMapping("/user")
@SessionAttributes(type=Teacher.class)
public class UserController {
@RequestMapping("/login")
public String login(Map<String,Object> map) {
String view = "success";
Teacher teacher = new Teacher("001","張三");
//在添加到request作用域,同時也添加了session作用域
map.put("teacher",teacher);
return "success";
}
}
4.@ModelAttribute
使用情況:
我們需要對資料進行更新,但我們隻能更新資料的某個屬性。
我們點選編輯之後,隻有一個輸入框讓我們輸入,用來更改那個屬性,我們輸入更改後的屬性值,更新的時候會發現,controller裡面的資料,傳入的對象除了更改的那個屬性值,其他的屬性值都是為null,我們不希望這種情況,是以,使用此注解
此注解用來修飾controller裡的某個方法,然後就會在執行controller中@RequestMapping的方法之前執行,把傳入的對象中的資料更新,之後執行修改操作的話,隻會把對象需要修改的屬性值更改,其他的屬性值不變(不為null了)
我個人覺得這樣好像比較麻煩,上面的情況有個更好的解決辦法,就是不要使用唯一的輸入框,而是使用多個輸入框,把不能更改的那幾項輸入框設定disable,之後送出表單也能成功傳入其他的屬性值
視圖解析器
工作流程
springmvc架構中,請求處理方法(Controller中的方法)執行完成後,最終傳回一個ModelAndView 對象。
Spring MVC 借助視圖解析器(ViewResolver)得到最終的視圖對象(View),最終的視圖可以是JSP ,也可能是Excel、JFreeChart 等各種表現形式的視圖
對于最終究竟采取何種視圖對象對模型資料進行渲染(也就是我們常說的把資料從request等作用域取出來顯示到頁面上),處理器并不關心,處理器工作重點聚焦在生産模型資料的工作上,進而實作MVC 的充分解耦
對于那些傳回String,View 或ModeMap 等類型的處理方法,Spring MVC 也會在内部将它們裝配成一個ModelAndView 對象,它包含了邏輯名和模型對象的視圖;
如下圖:
View
springmvc中的View其實是個接口,下面是常見的View接口的實作類
視圖類型 | 實作類 | |
---|---|---|
URL視圖類型 | InternalResourceView | 将JSP或其他資源封裝成一個視圖。被視圖解析器InternalResourceViewResolver預設使用。 |
JstlView | InternalResourceView的子類。如果JSP中使用了JSTL的國際化标簽,就需要使用該視圖類 | |
文檔視圖 | AbstractExcelView | Excel文檔視圖的抽象類 |
AbstractPdfView | PDF文檔視圖的抽象類 | |
報表視圖 | ConfigurableJasperReportsView | |
JasperReportsHtmlView | ||
JasperReportsPdfView | ||
JasperReportsXlsView | ||
JSON視圖 | MappingJackson2JsonView | 将資料通過Jackson架構的ObjectMapper對象,以JSON方式輸出 |
ViewResolver以及子類
ViewResolver和View一樣,也是個接口
視圖解析器類型 | 類名 | |
---|---|---|
解析為映射檔案 | UrlBasedViewResolver | 它簡單實作了ViewResolver接口, 不用任何映射就能通過邏輯視圖名稱通路資源 |
InternalResourceViewResolver | 将邏輯視圖名解析為一個路徑 | |
解析為bean | BeanNameViewResolver | 将邏輯視圖名解析為bean的name屬性,進而根據name屬性去找對應的bean |
ResourceBundleResolver | 和BeanNameViewResolver一樣,隻不過定義的view-bean都在一個properties檔案中,用這個類進行加載這個properties檔案 | |
XmlViewResolver | 和ResourceBundleResolver一樣,隻不過定義的view-bean在一個xml檔案中,用這個類來加載xml檔案 | |
解析為模版檔案 | VelocityViewResolver | 對Velocity模版引擎的支援 |
FreeMarkerViewResolver | 對FreeMarker模版引擎的支援 |
這裡,我隻介紹以下前兩種,也就是我們用過的類型。更多請參考我們下面給出的連結
AbstractCachingViewResolver,這個類為抽象類,實作了ViewResolver接口,抽象類隻能被繼承,無法建立執行個體。
UrlBasedViewResolver就是繼承于AbstractCachingViewResolver這個類,進而擴充了功能。
AbstractCachingViewResolver介紹:
這種視圖解析器會把它曾經解析過的視圖儲存起來,然後每次要解析視圖的時候先從緩存裡面找。
如果找到了對應的視圖就直接傳回,如果沒有就建立一個新的視圖對象,然後把它放到一個用于緩存的map中,接着再把建立的視圖傳回。
使用這種視圖緩存的方式可以把解析視圖的性能問題降到最低。
UrlBasedViewResolver介紹:
繼承了AbstractCachingViewResolver,主要就是提供的一種拼接URL的方式來解析視圖,它可以讓我們通過
prefix
屬性指定一個指定的字首,通過
suffix
屬性指定一個指定的字尾,然後把傳回的邏輯視圖名稱加上指定的字首和字尾就是指定的視圖URL了。
InternalResourceViewResolver介紹:
這個類是繼承于UrlBasedViewResolver,UrlBasedViewResolver具有的功能它都有,而且還有它自己的特性。從字面翻譯,InternalResourceViewResolver就是内部資源解析器。
InternalResourceViewResolver會把傳回的視圖名稱都解析為InternalResourceView對象,InternalResourceView會把Controller處理器方法傳回的模型屬性都存放到對應的request屬性中,然後通過RequestDispatcher在伺服器端把請求forword重定向到目标URL。
參考連結:Spring MVC-從零開始-view-ViewResolver
靜态資源通路
情景
如果我們想要通過一個url去通路我們項目中的一個圖檔、js檔案、視訊等靜态資源,會發現報404錯誤
原因是我們定義一個前置Servlet,處理了所有的url請求,但是,由于未能找到RequestMapping注解上的相比對的url,是以就會出現404錯誤
解決方法
在springmvc配置檔案中添
<mvc:default-servlet-handler/>
<mvc:annotation-driven></mvc:annotation-driven>
即可解決問題
之前給出的springmvc配置檔案中,其實已經添加了這兩個标簽,在這裡稍微介紹一下作用
<mvc:default-servlet-handler/>
作用:在SpringMVC上下文中,定義了一個DefaultServletHttpRequestHandler,它會對鄋DispatcherServlet處理的請求進行檢查,如果發現某個請求沒有對應的@RequestMapping進行處理,就會将該請求交個Web伺服器預設的Servlet進行處理,二預設的Servlet就會直接根據url去通路該資源
<mvc:annotation-driven></mvc:annotation-driven>
作用:通路靜态資源的同時,眼能夠正常的通路其他非靜态資源
兩個标簽都要添加
中文亂碼方法(補充)
1. 設定頁面編碼
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
2.配置過濾器
在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">
<display-name>SpringMVC Demo</display-name>
<!-- 中文轉碼必須加到核心控制器前面 -->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<!-- springmvc 核心控制器,将springMVC整合到項目裡-->
<servlet>
<servlet-name>springmvc-DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 配置spring mvc的元件:掃描controller, view resovle -->
<param-value>classpath:springmvc-config.xml</param-value>
</init-param>
<!-- 伺服器啟動時加載順序 -->
<load-on-startup>1</load-on-startup>
<!-- 異步請求處理支援 -->
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>springmvc-DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
更多方法,請檢視參考連結
參考連結:徹底解決springMVC中文亂碼
提問之前,請先看提問須知
點選右側圖示發起提問
或者加入QQ群一起學習
TornadoFx學習交流群:1071184701