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中文乱码

相关文章
相关标签/搜索