1. Spring MVC 中视图的实现原理,在Spring MVC 中实现重定向和转发,以及访问静态资源

@

目录

1.1 Spring MVC视图支持可配置

在Spring MVC中,视图 View 是支持定制的,例如我们之前在 springmvc.xml 文件中进行了如下的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--组件扫描-->
<context:component-scan base-package="com.rainbowsea.springmvc.controller"></context:component-scan> <!-- 视图解析器-->
<!-- 视图解析器-->
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
<!--作用于视图渲染的过程中,可以设置视图渲染后输出时采用的编码字符集-->
<property name="characterEncoding" value="UTF-8"/>
<!--如果配置多个视图解析器,它来决定优先使用哪个视图解析器,它的值越小优先级越高-->
<property name="order" value="1"/>
<!--当 ThymeleafViewResolver 渲染模板时,会使用该模板引擎来解析、编译和渲染模板-->
<property name="templateEngine">
<bean class="org.thymeleaf.spring6.SpringTemplateEngine">
<!--用于指定 Thymeleaf 模板引擎使用的模板解析器。模板解析器负责根据模板位置、模板资源名称、文件编码等信息,加载模板并对其进行解析-->
<property name="templateResolver">
<bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
<!--设置模板文件的位置(前缀)-->
<property name="prefix" value="/WEB-INF/templates/"/>
<!--设置模板文件后缀(后缀),Thymeleaf文件扩展名不一定是html,也可以是其他,例如txt,大部分都是html-->
<property name="suffix" value=".html"/>
<!--设置模板类型,例如:HTML,TEXT,JAVASCRIPT,CSS等-->
<property name="templateMode" value="HTML"/>
<!--用于模板文件在读取和解析过程中采用的编码字符集-->
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
</beans>

以上的配置表明当前 Spring MVC 框架使用的视图 View 是 Thymelea 的。

如果你需要换成其他的视图 View,修改以上的配置即可。这样就可以非常轻松的完成视图 View 的扩展。

这种设计是完成符合 OCP 开闭原则 的。视图 View 和框架是解耦合的,耦合度低扩展能力强。

视图 View 可以通过配置文件进行灵活切换。

1.2 Spring MVC支持的常见视图

Spring MVC支持的常见视图包括:

  1. InternalResourceView:内部资源视图(Spring MVC框架内置的,专门为JSP模板语法准备的)
  2. RedirectView:重定向视图(Spring MVC框架内置的,用来完成重定向效果)
  3. ThymeleafView:Thymeleaf视图(第三方的,为Thymeleaf模板语法准备的)
  4. FreeMarkerView:FreeMarker视图(第三方的,为FreeMarker模板语法准备的)
  5. VelocityView:Velocity视图(第三方的,为Velocity模板语法准备的)
  6. PDFView:PDF视图(第三方的,专门用来生成pdf文件视图)
  7. ExcelView:Excel视图(第三方的,专门用来生成excel文件视图)
  8. ......

1.3 实现视图机制的核心接口

实现视图的核心类与接口包括:

DispatcherServlet类(前端控制器):

  1. 职责:在整个Spring MVC执行流程中,负责中央调度。
  2. 核心方法:doDispatch


ViewResolver 接口(视图解析器)

  1. 职责:负责将 逻辑视图名 转换为 物理视图名 ,最终创建 View 接口的实现类,即视图实现类对象。

  2. 核心方法:resolveViewName

View 接口(视图):

  1. 职责:负责将模型数据 Model 渲染为视图格式(HTML代码),并最终将生成的视图(HTML代码)输出到客户端。(它负责将模板语言转换成 HTML代码)
  2. 核心方法:render

ViewResolverRegistry (视图解析器注册器):

负责在 web 容器(Tomcat)启动的时候,完成视图解析器的注册。

如果有多个视图解析器,会将视图解析器对象按照 order 的配置放入 List 集合。

总结:

实现视图的核心类和接口包括:ViewResolverRegistry,DispatcherServlet,ViewResolver,View

如果你想定制自己的视图组件:

  • 编写类实现 ViewResolver 接口,实现 resolveViewName方法,在该方法中完成 逻辑视图名 转换为物理视图名 ,并返回 View 对象。
  • 编写类实现 View 接口,实现 render 方法,在该方法中将模板语言转换成 HTML代码,并将HTML代码响应到浏览器。

如果 Spring MVC 框架中使用 Thymeleaf 作为视图技术。那么相关的类包括:

  • ThymeleafView
  • ThymeleafViewResolver

1.4 实现视图机制的原理描述

假设我们Spring MVC 中使用了 Thymeleaf 作为视图:

  1. 第一步:浏览器发送请求给 web 服务器
  2. 第二步:Spring MVC中的 DispatcherServlet 接收到请求
  3. 第三步:DispatcherServlet 根据请求路径分发到对应的 Controller
  4. 第四步:DispatcherServlet 调用 Controller 的方法
  5. 第五步:Controller 的方法处理业务并返回一个 逻辑视图名 给 DispatcherServlet
  6. 第六步:DispatcherServlet 调用 ThymeleafViewResovler 的 resolveViewName方法,将逻辑视图名 转换为 物理视图名 ,并创建 ThymeleafView 对象返回给 DispatcherServlet
  7. 第七步:DispatcherServlet 再调用 ThymeleafView 的 render 方法,render 方法将模板语言转换为 HTML代码,响应给浏览器,完成最终的渲染。

假设我们 Spring MVC 中使用了JSP作为视图:

  1. 第一步:浏览器发送请求给 web 服务器
  2. 第二步:Spring MVC 中的DispatcherServlet 接收到请求
  3. 第三步:DispatcherServlet 根据请求路径分发到对应的 Controller
  4. 第四步:DispatcherServlet 调用 Controller 的方法
  5. 第五步:Controller 的方法处理业务并返回一个 逻辑视图名 给 DispatcherServlet
  6. 第六步:DispatcherServlet 调用 InternalResourceViewResovlerresolverViewName 方法,将逻辑视图 转换为 物理视图名 ,并创建 InternalResourceView 对象返回给 DispathcerServlet
  7. 第七步:DispatcherServlet 再调用 InternalResourceView 的 render 方法,render 方法将模板语言转换为 HTML 代码,响应给浏览器,完成最终的渲染。

1.5 逻辑视图名到物理视图名的转换

逻辑视图名最终转换的物理视图名是什么,取决再 springmvc.xml 文件中视图解析器的配置: 假如视图解析器配置的是 ThymeleafViewResolver,如下:

<bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
<property name="characterEncoding" value="UTF-8"/>
<property name="order" value="1"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring6.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>

以下程序返回逻辑视图名:index

package com.rainbowsea.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller // 交给 Spring IOC 容器管理起来
public class IndexController { @RequestMapping("/")
public String index() {
return "index"; }
}

最终逻辑视图名 "index" 转换为物理视图名: /WEB-INF/templates/index.html


假如视图解析器配置的是 InternalResourceViewResolver,如下:

<!--    jsp视图解析器-->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>

以下程序返回逻辑视图名:index

package com.rainbowsea.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller // 交给 Spring IOC 容器管理起来
public class IndexController { @RequestMapping("/")
public String index() {
return "index"; }
}

最终逻辑视图名 "index" 转换为物理视图名:/ WEB-INF/templates/index.jsp

2. Thymeleaf视图

我们在学习前面内容的时候,采用的都是 Thymeleaf视图。我们再来测试一下,看看底层创建的视图对象是不是ThymeleafView

springmvc.xml 配置内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--组件扫描-->
<context:component-scan base-package="com.powernode.springmvc.controller"/> <!--视图解析器-->
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
<property name="characterEncoding" value="UTF-8"/>
<property name="order" value="1"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring6.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/thymeleaf/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
</beans>

Controller代码如下:

package com.rainbowsea.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller // 交给 Spring IOC 容器管理起来
public class IndexController { @RequestMapping("/")
public String index() {
return "index"; }
}

视图页面:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>index page</title>
</head>
<body>
<h1>index page</h1>
</body>
</html>

添加断点:在 DispatcherServlet 的 doDispatch( )方法的下图位置添加断点。

启动Tomcat,在浏览器地址栏上发送请求:http://localhost:8080/springmvc/index

程序走到以上位置,这行代码是调用对应的Controller,并且Controller最终会返回 ModelAndView对象:mv 按照我们之前所讲,返回 mv 之后,接下来就是视图处理与渲染,接着往下走,走到下图这一行:

这个方法的作用是处理分发结果,就是在这个方法当中进行了视图的处理与渲染,进入该方法:

进去之后走到上图位置:这个方法就是用来渲染页面的方法,再进入该方法:

走到上图位置就可以看到底层创建的是 ThymeleafView 对象。

3. JSP视图(了解)

我们再来跟一下源码,看看 JSP 视图底层创建的是不是 InternalResourceView对象。

我们前面说过 InternalResourceView是SpringMVC框架内置的,翻译为内部资源视图,SpringMVC把JSP看做是内部资源。可见JSP在之前的技术栈中有很高的地位。

不过,当下流行的开发中JSP使用较少,这里不再详细讲解。只是测试一下。

springmvc.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--组件扫描-->
<context:component-scan base-package="com.powernode.springmvc.controller"/> <!--视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>

Controller代码如下:

package com.powernode.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
public class IndexController {
@RequestMapping("/index")
public String toIndex(){
return "index";
}
}

视图页面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>index jsp</title>
</head>
<body>
<h1>index jsp!</h1>
</body>
</html>

启动web容器,添加断点跟踪:

通过测试得知:对于JSP 视图来说,底层创建的视图对象是 InternalResourceView。

4. 转发与重定向

4.1 转发和重定向区别

  1. 转发是一次请求,因此浏览器地址栏上的地址不会发生变化。
  2. 重定向是两次请求,因此浏览器地址栏上的地址会发生变化。
  3. 转发的代码实现:request.getRequestDispatcher("/index").forward(request, response);
  4. 重定向的代码实现:response.sendRedirect("/webapproot/index");
  5. 转发是服务器内部资源跳转,由服务器来控制。不可实现跨域访问。
  6. 重定向可以完成内部资源的跳转,也可以完成跨域跳转。
  7. 转发的方式可以访问 WEB-INF 目录下受保护的资源。
  8. 重定向相当于浏览器重新发送了一次请求,在浏览器直接发送的请求是无法访问 WEB-INF目录下受保护的资源的。
  9. 转发原理:
  1. 假设发送了 /a 请求,执行了 AServlet
  2. 在 AServlet 中通过 request.getRequestDispatcher("/b").forward(request,response); 转发到 BServlet
  3. 从AServlet 跳转到 BServlet 是服务器内部来控制的。对于浏览器而言,浏览器只发送了一个 /a 请求。
  1. 重定向原理:
  1. 假设发送了 /a 请求,执行了 AServlet
  2. 在 AServlet 中通过 response.sendRedirect("/webapproot/b")
  3. 此时服务器会将请求路径 /webapproot/b 响应给浏览器
  4. 浏览器会自发的再次发送 webapproot/b 请求来访问 BServlet
  5. 因此对于重定向来说,发送了两次请求,一次是 /webapproot/a ,另一次是 webapproot/b

更多关于 Java Web 转发和重定向的内容,大家可以移步至:️️️ JavaWeb 中 “转发”与 “重定向”的区别_java 重定向与转发-CSDN博客

以上所描述的是使用原生Servlet API来完成转发和重定向。在Spring MVC中是如何转发和重定向的呢?

5. 在 Spring MVC 中 “重定向” 以及 “转发”

5.1 在 Spring MVC 中使用 forward 实现转发

在Spring MVC中默认就是转发的方式,我们之前所写的程序,都是转发的方式。

在 Spring MVC 中是怎么通过代码完成转发的?
@RequestMapping("/a")
public String toA() {
// 返回的是一个逻辑视图名称
return "a"; // 转发 ThymeleafView
} 注意,当 return "a"; 的时候,返回一个逻辑视图名称,这种方式跳转到视图,默认采用的就是 forward 方式跳转过去的

只不过都是转发到 Thymeleaf 的模板文件xxx.html上。

那么,在Spring MVC中如何转发到另一个Controller上呢?可以使用Spring MVC的forward

使用格式如下:

return "forward:/b";转发到 /b ,这是一次请求,底层创建的视图对象是:internalResourceView对象
注意: "forward:/b" 这个已经不是逻辑视图名称了,是以转发的方式跳转,是一个资源路径。

package com.rainbowsea.springmvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller // 交给 Spring IOC 容器进行管理
public class ForwardController { @RequestMapping("/a")
public String toA() {
// 返回的是一个逻辑视图名称
//return "a"; // 采用SpringMVC的转发方式跳转到 /b
// 转发的时候,格式有特殊要求,return "forward:下一个资源的路径"
// 这种方式就不是逻辑视图名称了
return "forward:/b"; // 创建InternalResourceView对象 // 这个使用较多,重定向,url 中会显示资源路径
// return "redirect:/b";
} @RequestMapping("/b")
public String toB() {
// 返回的是一个逻辑视图名称
return "b";
}
}

视图页面:

A 视图页面编写:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>page a </title>
</head>
<body>
<h1>Page A !!!</h1> </body>
</html>

B 视图页面编写:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>page b</title>
</head>
<body>
<h1>Page B !!!</h1>
</body>
</html>

启动服务器,浏览器地址栏上输入:http://localhost:8080/springmvc/a

通过测试,可以顺利的完成转发,转发是一次请求,可以看到地址栏上的地址没有发生改变。

我们来跟踪一下源码,看看以上程序执行过程中,创建了几个视图对象,分别是什么?

通过源码的跟踪得知:整个请求处理过程中,一共创建了两个视图对象 ?

  • InternalResourceView

  • ThymeleafView

这说明转发底层创建的视图对象是:InternalResourceView

思考: 既然会创建 InternalResourceView,应该会对应一个视图解析器(InternalResourceViewResolver) ? 但是,我们在 springmvc.xml 文件中只配置了 ThymeleafViewResolver ,并没有配置 InternalResourceViewResolver ,这是为什么?

这是因为 forward: 后面的不是 逻辑视图名 ,而是一个 请求路径 ,因此,转发是不需要视图解析器的。

另外,转发使用的是 InternalResourceView ,也说明了转发是内部资源的跳转,(Internal 是内部的意思,Resource 是资源的意思。)

5.2 在 Spring MVC 中使用 redirect 实现重定向

redirect 是专门完成重定向效果的。和 forward 语法类似,只需要将之前的 return "forward:/b" 修改为 return "redirect:/b" 即可。

启动服务器,浏览器地址栏上输入:http://localhost:8080/springmvc/a

可见,重定向是两次请求,地址栏上的地址发生了改变。

可以看一下源码,在重定向的时候,Spring MVC创建哪个视图对象?

通过断点调试可以看出,当重定向的时候,SpringMVC会创建一个重定向视图对象:RedirectView。这个视图对象也是SpringMVC框架内置的。

另外可以看出重定向之后的第二次请求创建的视图对象就是ThymeleafView了。

注意:从springmvc应用重定向到springmvc2应用(跨域),语法是:

@RequestMapping("/a")
public String a(){
return "redirect:http://localhost:8080/springmvc2/b";
}

可以自行测试一下!!!

总结:

转发: return "forward:/b" 底层创建的是InternalResourceView对象

重定向: return "redirect:/b" 底层创建的是 RedirectView对象

6. mvc:view-controller 和 mvc:annotation-driven/ 的配合使用

<mcx:view-controller> 配置用于将某个请求映射到特定的视图上,即指定某一个 URL 请求到一个视图资源的映射,使得这个视图资源可以被访问。它相当于是一个独立的处理程序,不需要编写任何 Controller ,只需要指定 URL 和对应的视图名称就可以了。注意仅仅只是对应的 Controller 不需要写,其中对应的 html,jsp 或者是其他的视图是一定需要编写的。

一般情况下,<mvc:view-controller> 配置可以替代一些没有业务逻辑的 Controller,例如:首页,错误页面等。当用户访问配置的 URL时,框架将直接匹配到对应的视图,而无需再经过其他控制器的处理。

<mvc:view-controller > 配置的格式如下:

<mvc:view-controller path="/如何访问该页面" view-name="对应的逻辑视图名称" />

其中:

  • path:被映射的 URL 路径。

  • view-name:对应的逻辑视图名称。

例如,配置首页的映射:

<mvc:view-controller path="/" view-name="index" />

上述配置将会匹配上访问应用程序的根路径,如:http://localhost:8080/springmvc。当用户在浏览器中访问该根路径时,就会直接渲染名为 index 的视图。

重点:

在SpringMVC中,如果在springmvc.xml文件中配置了 <mvc:view-controller >,就需要同时在springmvc.xml文件中添加如下配置:< mvc:annotation-driven />

<mvc:annotation-driven/>

该配置的作用是:启用Spring MVC的注解。

如果没有以上的配置,Controller 就无法访问到。访问之前的Controller会发生 404 问题。

7. Spring MVC 中访问静态资源

一个项目可能会包含大量的静态资源,比如:css,js,images等。

由于我们 DispatcherServelt 的 url-pattern 的配置是 “/” 。

之前我们说过,这个“/” 代表的是除了jsp 请求之外的所有请求,也就是说访问应用中的静态资源,也会走 DispatcherServlet ,这会导致 404 错误,无法访问静态资源,如何解决,两种方案:

7.1 第一种方案:开启默认的 Servlet处理

第一种解决方案,开启默认的 Servlet处理
在Tomcat服务器中提供了一个默认的Servlet,叫做: org.apache.catalina.servlets.DefaultServlet
在CATALINA_HOME/conf/web.xml文件中,有这个默认的 Servlet的相关配置
不过,这个默认的Servlet默认情况下是不开启的
你需要在springmvc.xml文件中使用以下配置进行开启
<mvc:default-servlet-handler/>
<mvc:annotation-driven> 开启注解驱动
// 注意:上面这两个配置是一起的,不可以分开来使用。
> 开启之后的作用是:当你访问: http://localhost:8080/springmvc/static/img/touxiang.jpeg 的时候。
> 默认先走:DispatcherServlet,如果发生 404 错误的话,会自动走DefaultServlet,然后 DefaultServlet 帮你定位
> 静态资源

首先需要在 springmvc.xml 文件中添加以下配置,开启 默认Servlet处理静态资源 功能:

注意:下面两个配置是一起的,不可以分开来(就是,这两个配置都要有才行,不可以缺少其中的任意一个) 。

<!-- 开启注解驱动 -->
<mvc:annotation-driven /> <!--开启默认Servlet处理-->
<mvc:default-servlet-handler>

然后在 web.xml 文件中指定什么样的路径走其他 Servlet:

<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

以上配置 url-pattern 使用的也是 “/”,和 DispatcherServlet 一样。表示的含义是:同一个请求路径,先走 DispatcherServlet,如果找不到则走默认的Servlet。

默认的 Servlet 类中的代码已经由 Tomcat 服务器提供了实现了,一般不需要开发者自己编写。

上面的示例中,我们指定了 org.apache.catalina.servlets.DefaultServlet ,则 Tomcat 服务器会自动将请求转发到该类处理,再处理时,该类会根据请求的 URL 去查询 Web 应用的静态资源(如 HTML,CSS,JavaScript 和图片等),并将其返回给用户。

告诉大家一个好消息,以上在 web.xml 文件中的配置,我们也可以省略了,因为在 Tomcat 服务器中已经为我们提前配置好了,在 CATALINA_HOME/conf/web.xml 文件中,如下:

因此我们只需要在springmvc.xml文件中启用这个默认的Servlet即可:<mvc:default-servlet-handler>

7.2 第二种方案:使用 mvc:resources 标签配置静态资源

第二种解决方案:配置静态资源处理,在springmvc.xml文件中添加如下配置
<mvc:resources mapping="/static/**" location="/static/"></mvc:resources>
<mvc:annotaiton-driven> //开启注解驱动
同样这两个是一起配合使用的,不可以分开来
> 作用:当请求路径符合 /static/**的时候,去 /static/位置找资源

访问静态资源,也可以在springmvc.xml文件中添加如下的配置:

<!-- 开启注解驱动 -->
<mvc:annotation-driven /> <!-- 配置静态资源处理 -->
<mvc:resources mapping="/static/**" location="/static/" />

表示凡是请求路径是"/static/"开始的,都会去"/static/"目录下找该资源。

注意:要想使用 <mvc:resources> 配置,必须开启注解驱动 <mvc:annotation-driven />

8. 总结:

  1. ViewResolver 接口,视图解析接口(ThymeleafViewResolver 实现了 ViewResolver 接口,InternalResourceViewResolver 也是实现了

    ViewResolver接口...),这个接口作用是将逻辑视图名称 转换为 物理视图名称,并且最终返回一个 view 接口对象,核心方法是:View resolveViewName(String viewName,Locale locale) throws Exception;
  2. View 接口,视图接口(ThymeleafView 实现了接口,InternalResourceView 也实现了 View 接口)这个接口做什么的?这个接口负责模板语法的字符串转换成 html代码,并且将html代码响应给浏览器。(渲染)核心方法是 void render(@Nullable Map<String,?> model,HttpServletRequest request, HttpServletResponse response) throws Exception;
  3. 注意:默认的
在 Spring MVC 中是怎么通过代码完成转发的?
@RequestMapping("/a")
public String toA() {
// 返回的是一个逻辑视图名称
return "a"; // 转发 ThymeleafView
} 注意,当 return "a"; 的时候,返回一个逻辑视图名称,这种方式跳转到视图,默认采用的就是 forward 方式跳转过去的
  1. forward 的转发格式:return "forward:/b";转发到 /b ,这是一次请求,底层创建的视图对象是:internalResourceView对象。

  2. redirect 重定向格式:return "redirect:/b";转发到 /b,这是两次请求,底层创建的视图对象是:RedirectView对象。注意语法:必须以 : redirect:开始

  3. thymeleaf 模板字符串,这个是浏览器不认识的。ThymeleafView进行解析将其转换成html响应给浏览器。

  4. mvc:view-controller 和 mvc:annotation-driven/ 的配合使用,不需要编写任何 Controller ,只需要指定 URL 和对应的视图名称就可以了。注意仅仅只是对应的 Controller 不需要写,其中对应的 html,jsp 或者是其他的视图是一定需要编写的。注意:两个配置都要写上,缺一不可

  5. Spring MVC 中访问静态资源:两种方式:

    1. 第一种方案:开启默认的 Servlet处理
    <!-- 开启注解驱动 -->
    <mvc:annotation-driven /> <!--开启默认Servlet处理-->
    <mvc:default-servlet-handler>
    1. 第二种方案:使用 mvc:resources 标签配置静态资源
<!-- 开启注解驱动 -->
<mvc:annotation-driven /> <!-- 配置静态资源处理 -->
<mvc:resources mapping="/static/**" location="/static/" />

9. 最后:

“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”

Spring MVC 中视图的实现原理,在Spring MVC 中实现重定向和转发,以及访问静态资源的更多相关文章

  1. [J2EE]Spring MVC中访问静态资源[转]

    1 文献来源 SpringMVC访问静态资源的三种方式(转) - 博客园 SpringMVC访问静态资源的三种方式 + 提供解决方案的原作者 2 前言 2.1 访问不到静态资源起因 如果web.xml ...

  2. Spring MVC访问静态资源

    http://www.cnblogs.com/yank/p/4477204.html SpringMVC访问静态资源 在SpringMVC中常用的就是Controller与View.但是我们常常会需要 ...

  3. Spring Mvc Web 配置拦截规则与访问静态资源 (三)

    拦截规则配置 1. *.do <!-- Processes application requests --> <servlet> <servlet-name>app ...

  4. spring访问静态资源出错,No mapping found for HTTP request with URI xxx/resources/js/jquery.min.js...

    问题:spring访问静态资源出错,No mapping found for HTTP request with URI xxx/resources/js/jquery.min.js... web.x ...

  5. idea中JSP页面不能访问静态资源(图片,js,css)

    必须配置SpringMvc对访问静态资源的支持,idea默认就是在main/webapp 下的文件路径,要在web-info同级的resource文件下放置,JSP中 ${pageContext.re ...

  6. 0055 <mvc:default-servlet-handler />不能同时访问静态资源和动态资源的问题

    刚才在折腾的时候,发现applicationContext.xml中配置了<mvc:default-servlet-handler />后,能访问静态资源,却不能访问动态资源了:注释掉之后 ...

  7. spring boot默认访问静态资源

    演示spring boot默认可以直接访问静态资源的2种方法: 第一种:在src/main/resources资源目录下创建一个名为"static"的文件夹(该文件夹的名称是规定死 ...

  8. Spring Boot整合Servlet,Filter,Listener,访问静态资源

    目录 Spring Boot整合Servlet(两种方式) 第一种方式(通过注解扫描方式完成Servlet组件的注册): 第二种方式(通过方法完成Servlet组件的注册) Springboot整合F ...

  9. Spring MVC 访问静态资源

    当我们不通过控制器,想直接访问网站上的静态资源时,由于DispatcherServlet的url-patten的通配符的限制,导致系统会认为你访问的是个url映射,这时需要配置一个东西就可以解决问题了 ...

  10. spring mvc 访问静态资源404

    访问比如css js出现404提示 在spring的配置文件中加上如下代码即可 <!-- 静态资源404 --> <mvc:resources location="/res ...

随机推荐

  1. java学习之旅(day.14)

    可变字符串 StringBuffer:可变长字符串,运行效率慢,线程安全 StringBuilder:可变长字符串,运行效率快,线程不安全 package com.zhang.lei; //Strin ...

  2. openstack 错误(报错)集合

    1. 执行nova命令报错: ERROR (CommandError): You must provide a username or user ID via --os-username, --os- ...

  3. Java应用的优雅停机

    一. 优雅停机的概念 优雅停机一直是一个非常严谨的话题,但由于其仅仅存在于重启.下线这样的部署阶段,导致很多人忽视了它的重要性,但没有它,你永远不能得到一个完整的应用生命周期,永远会对系统的健壮性持怀 ...

  4. Nginx 修饰符 Location 详解

    概述 location 指令可以用在虚拟服务器 server 部分,并且意味着提供来自客户端的 URI 或者内部重定向访问. location 的定义如下: location [modifier] u ...

  5. Android OpenMAX(三)高通OMX组件实现基础

    上一节了解了OMX组件实现的基础内容,这一节我们以高通OMX实现为例,简单看看如何实现一个OMX组件.本节代码参考自: omx_core_cmp.cpp qc_omx_component.h omx_ ...

  6. 《iOS面试之道》-勘误2

    一.如何保证NSTimer不受Runloop的影响,准时触发 书中提到两种方案, 一种是改变timer加入到runloop中的Mode,为CommonModes不受Runloop的Mode影响 第二种 ...

  7. 8.21考试总结(NOIP模拟45)[打表·蛇·购物·ants]

    有型的东西终究会消逝,不过--终于,这份回忆还是永远不朽的- 前言 这次考试暴露出来了不少问题. 比如答题策略策略不当导致 T2 的 65pts 暴力根本没有打. 知识遗忘太快不牢固,T4 是之前的一 ...

  8. MySQL学习笔记-数据控制语言

    SQL-数据控制语言(DCL) DCL语句用于管理数据库用户,控制数据库的访问权限 一. 管理用户 1. 查询用户 # 访问mysql数据库 use mysql; #查询user表 select * ...

  9. Linux网络驱动

    1 简介 1.1 硬件说明 嵌入式网络硬件分为:MAC和PHY.MAC一般时SOC内置,PHY是外部器件. (1)SOC内部没有MAC 如果SOC内部没有网络MAC外设,可使用外置的MAC,一般外置的 ...

  10. Android应用程序启动流程浅析-(三万字长文慎点&Android14)

    在Android桌面Launcher源码浅析中介绍了Android的桌面程序Launcher是如何响应用户点击事件并启动App的,这篇文章继续介绍App在Android系统层是的启动流程. 一.启动流 ...