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

SpringMVC框架是基於Spring框架,可讓咱們更爲方便的進行Web的開發,實現先後端分離javascript

思路和原理

咱們以前仿照SpringMVC定義了一個自定義MVC框架,二者的思路其實都是同樣的。css

建議結合兩篇文章進行學習html

JSP學習筆記(6)—— 自定義MVC框架java

首先,提供一個前置攔截器(DispatchServlet),攔截url請求,以後,根據url請求,跳轉到Controller層,執行操做,以後再返回數據jquery

入門

個人demo是使用了maven框架git

1.建立maven項目

按照下圖進行配置
github

2.添加依賴

修改pom.xml,添加依賴web

剛開始的時候,使用的是最新版本(5.x.x),而後發現有個奇怪的錯誤,折騰了許久找不到方法,因而便用了4.x.x版本的,果真沒有出現問題了,果真是新版本都很差用。。ajax

<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模板新建的項目,因此項目結構還須要添加一些文件夾spring

在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中文亂碼

相關文章
相關標籤/搜索