目录
6、InternalResourceViewResolver(一般用来解析JSP)
注:这次的笔记使用的模块是上一篇的 SpringMVC-demo3
SpringMVC中的视图是 View 接口,视图的作用渲染数据,将模型Model中的数据展示给用户
SpringMVC视图的种类很多,默认有 转发视图(InternalResourceView) 和 重定向视图(RedirectView)
当工程引入 jstl 的依赖,转发视图会自动转换为 JstlView
若使用的视图技术为Thymeleaf,在SpringMVC的配置文件中配置了Thymeleaf的视图解析器,由此视图解析器解析之后所得到的是 ThymeleafView
1、ThymeleafView
当控制器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被SpringMVC配置文件中所配置的视图解析器解析,视图名称拼接视图前缀和视图后缀所得到的最终路径,会通过转发的方式实现跳转
① 在 src/main/webapp/WEB-INF/templates 目录下创建 test_view.html 页面,用来放存放的跳转链接
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>视图</title>
</head>
<body>
<!-- 测试ThymeleafView -->
<a th:href="@{/testThymeleafView}">测试ThymeleafView</a>
</body>
</html>
② 在 TestController 中添加打开 test_view.html 所需的方法 ,之后运行需要打开的页面是http://localhost:8080/SpringMVC_demo3/testThymeleafView
@RequestMapping("/test_view")
public String testView(){
return "test_view";
}
③ 创建 ViewController 类用来存放这次笔记所需的控制器
@Controller
public class ViewController {
@RequestMapping("/testThymeleafView")
public String testThymeleaf(){
return "success";
}
}
思考:如何确定这是 ThymeleafView 对象
Ⅰ、在 ViewController 类的 testThymeleaf 方法的 return 语句打上断点,调试运行,在调试器的方法栈中找到 doDispatcher:1061 方法,在打开的页面的两行打上断点,如下图
Ⅱ、通过调试,在运行到 1078 行时,进入到 processDispatchResult 方法中,在执行到下图的 render 方法时,步入方法
Ⅲ、执行到下图 resolveViewName 方法就是处理 mv 的方法,其中 locale 是本地的语言
再下一步可以发现 mv 是 Thymaleaf 类
2、转发和重定向的区别
1、请求次数
重定向是浏览器向服务器发送一个请求并收到响应后再次向一个新地址发出请求,转发是服务器收到请求后为了完成响应跳转到一个新的地址;重定向至少请求两次,转发请求一次;
2、地址栏不同
重定向地址栏会发生变化,转发地址栏不会发生变化;
3、是否共享数据
重定向两次请求不共享数据,转发一次请求共享数据(在request级别使用信息共享,由于重定向请求两次,而request是一次请求有效,所以使用重定向必然出错);
4、跳转限制
重定向可以跳转到任意URL,转发只能跳转本站点资源(因为转发是发生在服务器内部);
5、发生行为不同
重定向是客户端行为,转发是服务器端行为;
3、转发视图(forward:)
SpringMVC 中默认的转发视图是 InternalResourceView
SpringMVC中创建转发视图的情况:
当控制器方法中所设置的视图名称以"forward:"为前缀时,创建InternalResourceView视图,此时的视图名称不会被SpringMVC配置文件中所配 置的视图解析器解析,而是会将前缀"forward:"去掉,剩余部分作为最终路径通过转发的方式实现跳转
例如"forward:/","forward:/employee"
① 在 ViewController 类中添加方法,并在 return 语句打上断点
// 测试转发视图
// 通过这个方法转发到 /testThymeleafView
@RequestMapping("/testForward")
public String testForward(){
// 这个过程会创建两次视图,一个是将 forward: 去掉后的转发视图,第二个是由于 /testThymeleafView 是一个请求映射,所以会创建对应的视图
return "forward:/testThymeleafView";
}
② 在 test_view.html 页面添加测试的超链接
<!-- 测试转发视图 -->
<a th:href="@{/testForward}">测试转发视图w</a><br>
③ 调试运行,在 doDispatch:1061 中进入 processDispatchResult 方法,再进入 render 方法
可以看到第一次创建的视图参数如下:
④ 按 F9 恢复程序,由于转发到 /testThymeleafView,程序会再次创建视图。再次执行上述操作, 可以看到第二次创建的视图参数如下:
4、重定向视图
SpringMVC中默认的重定向视图是 RedirectView
当控制器方法中所设置的视图名称以 "redirect:" 为前缀时,创建 RedirectView 视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀"redirect:"去掉,剩余部分作为最终路径通过重定向的方式实现跳转
例如"redirect:/","redirect:/employee"
① 在 ViewController 类中添加方法,并在 return 语句打上断点
// 测试重定向视图
// 通过这个方法重定向到 /testThymeleafView
@RequestMapping("/testRedirect")
public String testRedirect(){
return "redirect:/testThymeleafView";
}
② 在 test_view.html 页面添加测试的超链接
<!-- 测试重定向视图 -->
<a th:href="@{/testRedirect}">测试重定向视图</a><br>
③ 调试运行,在 doDispatch:1061 中进入 processDispatchResult 方法,再进入 render 方法
可以看到创建的 View 视图参数如下,为 RedirectView
④ 按 F9 恢复程序,由于重定向到 /testThymeleafView,程序会再次创建视图。再次执行上述操作, 可以看到第二次创建的视图参数如下:
5、视图控制器view-controller
当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理器方法使用view-controller标签进行表示
注:当SpringMVC中设置任何一个view-controller时,其他控制器中的请求映射将全部失效,此时需要在SpringMVC的核心配置文件中设置开启mvc注解驱动的标签: <mvc:annotation-driven />
① 将 TestController 类中跳转到首页的方法注释掉
② 在 springMVC.xml 中设置视图控制器view-controller
注:这里的 view-name 属性报错没有关系,一样能正常打开页面
<!--
设置视图控制器view-controller
path:设置处理的请求地址
view-name:设置请求地址所对应的视图名称
-->
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
③ 这时,在打开的首页随意打开一个链接,会发现报错 404,只需要在 springMVC.xml 中添加以下内容,再重新部署即可
<!-- 开启mvc的注解驱动 -->
<mvc:annotation-driven/>
6、InternalResourceViewResolver(一般用来解析JSP)
① springMVC 的配置
<!-- 配置扫描组件 -->
<cntext:component-scan base-package="com.zyj.mvc.controller"></cntext:component-scan>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/templates/"></property>
<!-- 后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
② web.xml 与之前的一样,配置编码过滤器和DispatcherServlet
<!-- 配置编码过滤器 -->
<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>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置SpringMVC的前端控制器DispatcherServlet -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
③ index.jsp 跳转的链接
<a href="${pageContext.request.contextPath}/success">success.jsp</a>
④ 控制器方法
// 访问success.jsp
@RequestMapping("/success")
public String success(){
return "success";
}