Spring框架學習筆記(3)——SpringMVC框架


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,,會被自動加入前綴和后綴,注意,這里是進行的請求轉發

除此之外,我們還可以加上forwardredirect前綴來進行請求轉發或重定向

但是,如果使用這兩種前綴,之后視圖解析器就不會自動添加前綴和后綴了。所以,我們得指定具體跳轉的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注解的常用屬性說明

屬性 說明
value 請求攜帶參數的參數名
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類似的還有這兩個RequestHeaderCookieValue

這兩個注解我現在沒怎么用到,暫時了解一下,不作補充

  • RequestHeader注解,主要是用來獲得請求頭的數據
  • CookieValee注解,主要是用來獲得一個cookieValue

返回json數據

我們使用@ResponseBody,方法返回實體類或者集合的時候,springmvc就會自動幫我們轉為json數據

使用之前需要導入這兩個jar,jackson-core.jarjackson-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>

UserController.java

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)

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
@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默認使用。
URL視圖類型 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
解析為bean ResourceBundleResolver 和BeanNameViewResolver一樣,只不過定義的view-bean都在一個properties文件中,用這個類進行加載這個properties文件
解析為bean 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中文亂碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM