SpringMVC中的视图是View接口,视图的作用渲染数据,将模型Model中的数据展示给用户
SpringMVC视图的种类很多,默认有转发视图(InternalResourceView)和重定向视图(RedirectView)
当工程引入jstl的依赖,转发视图会自动转换为JstlView
若使用的视图技术为Thymeleaf,在SpringMVC的配置文件中配置了Thymeleaf的视图解析器,由此视图解析器解析之后所得到的是ThymeleafView
1.1ThymeleafVIew
当控制器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被SpringMVC配置文件中所配置的视图解析器(ThymeleafViewResolver)解析,视图名称拼接视图前缀和视图。
我们当前的解析器为:
<?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/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--扫描控制层组件--> <context:component-scan base-package="com.rgf.controller"></context:component-scan> <!--配置Thymeleaf视图解析器--> <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> <property name="order" value="1"/> <property name="characterEncoding" value="UTF-8"/> <property name="templateEngine"><!--模板引擎--> <bean class="org.thymeleaf.spring5.SpringTemplateEngine"> <property name="templateResolver"><!--模板解析器--> <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"> <!--/WEB-INF/templates/index.html--> <!--视图前缀+逻辑视图+视图后缀就是我们完整的物理视图,即访问index.html,不用完整路径,即index即可进行访问--> <!--视图前缀--> <property name="prefix" value="/WEB-INF/templates/"/> <!--视图后缀--> <property name="suffix" value=".html"/> <property name="templateMode" value="HTML5"/> <property name="characterEncoding" value="UTF-8" /> </bean> </property> </bean> </property> </bean> </beans>
使用的视图解析器为:ThymeleafViewResolver,被该解析器解析之后为:ThymeleafView
我们在控制方法进行debug:
我们在debug的一个框里面会展示我们当前的一个方法栈,当前方法处于该窗口中, 我们发现DispatcherServlet,找到对应行数:1061行。
存在于方法栈中的方法,在该框中越往上的方法跟当前所要执行的方法的断点所在的位置越近。
越往下,跟当前断点所对应的位置越远。从该方法栈里面从最下面一步步调用到当前所打得断点的位置。
此时我们查看到:
我们所获取的是一个ModelAndView对象。
再次打断点的位置的作用为执行当前的我们的一个的转发结果 ,此时跳过断点之后我们就已经获取到ModelAndVIew。
此时我们跳过断点之后,我们会发现:
此时的mv已经获取数据: “ModelAndView ["view="success" ;model={testRequestScope="Hello,ModelAndView"}。
箭头依次为:下一步(F8)、进入某个方法中(F7)、强制进入某个方法(ALT+Shift+F7)、从某个方法中跳出(shift+F8)、跳过断点(ALT+F9)。
CTRL+G,查找指定行。
我们在进行debug的时候,可以点击下面的红点进行管理断点所在的位置。
我们选中某一个,点击上端的-即可。
我们创建一个新的controller之后,先在我们的index.html新建一个超链接:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>首页</title> </head> <body> <h1>index.html</h1> <a th:href="@{/hello}">测试@RequestMapping注解所标识的位置</a><br> <a th:href="@{/abc}">测试@RequestMapping注解的value属性</a> <form th:action="@{/hello}" method="post"> <input type="submit" value="测试@RequestMapping注解的method属性"> </form> <a th:href="@{/hello?username=admin}">测试@RequestMapping注解的params属性(第一种)</a><br> <a th:href="@{/hello(username='admin')}">测试@RequestMapping注解的params属性(第二种)</a><br> <a th:href="@{/aaa/test/ant(username='admin')}">测试@RequestMapping注解支持ant风格的路径</a><br> <br> <form th:action="@{/param/servletAPI}" method="post"> 用户名: <input type="text" name="username"><br> 密码: <input type="password" name="password"><br> 提交: <input type="submit" value="登录"><br> </form> <a th:href="@{/param/servletAPI}"></a> <hr> <a th:href="@{/test/mav}">测试通过ModelAndView向请求域共享数据</a> <hr> <a th:href="@{/test/view/thymeleaf}">测试SpringMVC的视图ThymeleafView</a> </body> </html>
我们在新建的controller里面定义新的方法,我们进行打断点如下所示:
我们点击页面我们所测试的ThymeleafView:
我们发现首先进入
我们跳过之后进入如下所示:
继续跳过之后进入:
此方法为执行处理我们转发的结果。我们进入该方法进行查看:
我们进去之后,在该处也打一个断点,此处为渲染的意思。此时即可处理我们当前的ModelAndView,然后把我们Model当中的数据共享在我们的请求域中,把我们所设置的逻辑视图创建相对应的视图对象,然后去找到我们相对应的视图。即为页面,然后进行跳转。
此时里面的viewName即为我们设置的success.
此处的 resolveViewName,解析我们当前的视图名称来得到一个视图。所以我们当前所创建的视图只跟我们的视图名称有关。只跟我们当前方法的字符串类型的返回值有关系。
此时,我们的view为ThymeleafView.
ThymeleafView创建过程中没有任何的前缀。
2.InternalRersourceView
SpringMVC中默认的转发视图是InternalResourceView
SpringMVC中创建转发视图的情况:
当控制器方法中所设置的视图名称以"forward:"为前缀时,创建InternalResourceView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀”forward:"去掉,剩余部分作为最终路径通过转发的方式实现跳转
我们新建如下链接:
我们创建新的方法:
我们将其转发到:
我们在此处进行打断点:
运行之后,点击超链接:
点击之后进入断点:
跳过之后继续查看进入:
其中的render为渲染视图,来处理ModelAndView.
我们继续进入里面:
此时我们的mv:"ModelAndView[view="forward:.test/model";此时的视图名称如下所示。
跳转完之后,我们查看View里面的值:
此时的view为InternalResourceView,url为/test/model;将其转发到该url.
此时会创建两个视图,首先转发前会创建InternalResourceView这个视图,跳转成功之后,dispatcherServlet会进行处理forward:.test/model这个请求,即会进入另一个视图。而另一个视图默认为ThymeleafView。
此时我们将断点跳过之后,会再次进入如下断点:
我们继续向下执行的时候,我们的视图名称为success.即可进行跳转到该页面。此时创建出来的视图为ThymeleafView。
此时的过程为点击链接之后,进行跳转到forward:/test/model,携带hello,Model,跳转到success界面。如下所示:
我们比较常用的是ThymeleafView,我们并不是直接跳转页面,而是通过ThymeleafView的视图解析器ThymeleafViewResolver来解析当前的视图,去解析当前页面中ThymeleafView中的语法,才能去渲染页面,看到一个动态数据。
当我们使用
界面是会被Thymeleaf进行渲染的,但是我们使用如下方式进行转发到该界面的时候
界面是不会被Thymeleaf所渲染的,仅仅是一个简单的转发。
如果我们所使用的是一种jsp视图的话:我们需要在配置文件中配置的视图解析器为:InternalResourceViewResolver
此时创建的转发视图也是InternalResourceViewResolver。但是通InternalResourceViewResolver进行转发的是无法进行页面渲染的,ThymeleafView的语法无法被解析,但是ThymeleafView的这种视图是可以进行页面渲染的。
3.RedirectView
SpringMVC中默认的重定向视图是RedirectView
当控制器方法中所设置的视图名称以"redirect:"为前缀时,创建RedirectView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀”redirect:"去掉,剩余部分作为最终路径通过重定向的方式实现跳转
我们创建如下链接:
我们创建新的方法:
@RequestMapping("/test/view/redirect") public String testRedirectView(){ return "redirect:/test/model"; }
此时我们将项目进行运行:
我们点击如下所示:
我们发现继续进入断点:
我们继续将断点往下走:
我们继续进入里面:
此时我们的mv:"ModelAndView[view="redirect:.test/model";此时的视图名称如此所示。
跳转完之后,我们查看View里面的值:
此时的view为RedirectView。此时跳转过之后,会继续访问test/model,断点会继续进入该方法:
此时再次创建的视图名称为ThymeleafView。
此时查看我们所跳转的界面的地址拦:
一般而言,当我们的业务逻辑处理成功的时候用转发,处理失败的时候用重定向。登录成功用转发,登录失败用重定向。
重定向所跳转到的绝对路径就会被浏览器所解析,而浏览器解析的绝对路径是把/解析为localhost:8080.而我们当前设置的重定向的路径,都可以成功进行跳转,说明在跳转过程中会自动在绝对路径前面加一个上下文路径。
4.视图控制器view-controller
当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理器方法使用view-controller标签进行表示。
例如我们要进行跳转到首页:
我们必须要有这个方法才能跳转到index.html首页。
我们利用view-controller,在配置文件里面进行配置如下:
<?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/c" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--扫描控制层组件--> <context:component-scan base-package="com.rgf.controller"></context:component-scan> <!--配置Thymeleaf视图解析器--> <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> <property name="order" value="1"/> <property name="characterEncoding" value="UTF-8"/> <property name="templateEngine"><!--模板引擎--> <bean class="org.thymeleaf.spring5.SpringTemplateEngine"> <property name="templateResolver"><!--模板解析器--> <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"> <!--/WEB-INF/templates/index.html--> <!--视图前缀+逻辑视图+视图后缀就是我们完整的物理视图,即访问index.html,不用完整路径,即index即可进行访问--> <!--视图前缀--> <property name="prefix" value="/WEB-INF/templates/"/> <!--视图后缀--> <property name="suffix" value=".html"/> <property name="templateMode" value="HTML5"/> <property name="characterEncoding" value="UTF-8" /> </bean> </property> </bean> </property> </bean> <!--视图控制器:为当前的请求直接设置视图名称实现页面跳转--> <mvc:view-controller path="/" view-name="index"></mvc:view-controller> </beans>
我们即可直接进行跳转该页面。
我们将该方法进行注掉:
package com.rgf.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class ProtalController { @RequestMapping("/") public String protal(){ return "index"; } }
进行重新部署,我们回到首页,进行刷新:
仍然可以访问首页。
此时点击其他链接,发现出现了:404
如果我们在当前配置文件中使用了view-controller视图控制器,当前只有视图控制器所设置的请求才能被处理。此时要在配置文件里再加一个标签:<mvc:annotation-driver/>,开启mvc的注解驱动
<?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/c" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--扫描控制层组件--> <context:component-scan base-package="com.rgf.controller"></context:component-scan> <!--配置Thymeleaf视图解析器--> <bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"> <property name="order" value="1"/> <property name="characterEncoding" value="UTF-8"/> <property name="templateEngine"><!--模板引擎--> <bean class="org.thymeleaf.spring5.SpringTemplateEngine"> <property name="templateResolver"><!--模板解析器--> <bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"> <!--/WEB-INF/templates/index.html--> <!--视图前缀+逻辑视图+视图后缀就是我们完整的物理视图,即访问index.html,不用完整路径,即index即可进行访问--> <!--视图前缀--> <property name="prefix" value="/WEB-INF/templates/"/> <!--视图后缀--> <property name="suffix" value=".html"/> <property name="templateMode" value="HTML5"/> <property name="characterEncoding" value="UTF-8" /> </bean> </property> </bean> </property> </bean> <!--开启mvc的注解驱动--> <mvc:annotation-driver/> <!--视图控制器:为当前的请求直接设置视图名称实现页面跳转 若设置视图控制器,则只有视图控制器所设置的请求会被处理,其他的请求将全部404 此时必须再配置一个标签 <mvc:annotation-driver/>,从而开启mvc的注解驱动 <mvc:annotation-driver/>,在好多功能里面都要使用这个标签,(在处理静态资源的时候,处理ajax请求,处理json数据的时候),都是要加上这个标签。 --> <mvc:view-controller path="/" view-name="index"></mvc:view-controller> </beans>
此时设置之后,我们的链接都可以进行点击。即视图解析器和@RequestMapping实现的界面跳转都可以实现。此时我们再次访问首页,其他界面都可以进行点击。
点击其他的也可以成功进行跳转: