天天看點

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

SpringMVC架構是基于Spring架構,可以讓我們更為友善的進行Web的開發,實作前後端分離

思路和原理

我們之前仿照SpringMVC定義了一個自定義MVC架構,兩者的思路其實都是一樣的。

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

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

首先,提供一個前置攔截器(DispatchServlet),攔截url請求,之後,根據url請求,跳轉到Controller層,執行操作,之後再傳回資料

入門

我的demo是使用了maven架構

1.建立maven項目

按照下圖進行配置

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

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檔案夾

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

把java檔案夾設定為source directory

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

在java檔案夾下建立自己的包名,然後建立一個controller檔案夾和model檔案夾,順便也建立一個resources的檔案夾,和上面同樣的步驟,設定為resources directory

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

除此之外,還需要在webapp檔案夾下建立一個views檔案夾

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

4.設定Tomcat配置

我這裡是設定好了,沒有設定的話,是沒有下拉菜單的,但是有個add configuration的選項

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

選擇tomcat的設定,選擇local,如果沒有Tomcat的選項,可以點選選項最下面的show more

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

點選之後,添加構造物

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

選擇那個exploded的選項

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

設定url

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

之後開始運作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>
           

之後就是可以跳轉到了頁面

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

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資料

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

處理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 對象,它包含了邏輯名和模型對象的視圖;

如下圖:

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

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

提問之前,請先看提問須知

點選右側圖示發起提問

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

或者加入QQ群一起學習

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

TornadoFx學習交流群:1071184701

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