目录
在springmvc中,我们返回的数据默认都会构成ModelAndView,这个View就是要跳转的页面,如果我们返回一个字符串,那么该字符串就会被默认视图解析器解析作为转发路径。当然,视图解析器也可以自定义。
springmvc中默认视图解析器是InternalResourceViewReslover,用于解析handler返回的信息。

看类图可以发现它继承了UrlBasedViewResolver,下面来看看InternalResourceViewReslover和UrlBasedViewResolver这2个类的注释

InternalResourceViewReslover注释大概意思就是建议我们将文件放到WEB-INF目录下,这样可以阻止直接请求访问。还有一个注意事项就是 InternalResourceViewReslover是作为最后一个解析器进行解析的。注意:springmvc包含多种解析器,还可能有自定义解析器。下面再看下UrlBasedViewResolver这个类注释


通过类上面的注释,我们可以知道UrlBasedViewResolver会将返回值作为视图名称解析解析,寻找项目中的资源,同时还会添加前缀和后缀,前缀和后缀都是自定义的。该类还会解析返回值十分是forward:或者redirect:开头的,如果是,那么就会进行转发或者重定向到对应资源,而不是进行标准视图解析。
为了测试方便,创建一个jsp页面

- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>成功title>
- head>
- <body>
- <h1>测试成功!!!h1>
- body>
- html>
通过上面的注释,可以知道,我们可以给默认视图解析器配置一个prefix和suffix,下面在配置文件中进行配置
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/WEB-INF/pages/"/>
- <property name="suffix" value=".jsp"/>
- bean>
下面编写java代码进行测试
- @RequestMapping("/view")
- @Controller
- public class ViewController {
-
- @RequestMapping("/f1")
- public String f1() {
- System.out.println("f1.....");
- return "success";
- }
- }
上面代码就可以知道,f1方法会转发到/WEB-INF/pages/success.jsp页面,使用postman进行测试

测试没有问题,下面写法就是转发和重定向,就不测试了
- @RequestMapping("/f2")
- public String f2() {
- System.out.println("f2.....");
- //会转发到f1,以当前路径为参考,不会添加prefix和suffix,
- return "forward:f1";
- }
-
- @RequestMapping("/f3")
- public String f3() {
- System.out.println("f3.....");
- //会重定向到f1,以当前路径为参考,不会添加prefix和suffix,
- return "redirect:f1";
- }
通过上面的默认视图,可以发现局限性是很大的,这是,我们就可以自定义视图,下面来进行说明。
自定义视图主要分为4个部分,如下
下面就是具体的代码实现,先创建自己的视图解析
- @Component("myView")
- public class MyView extends AbstractView {
- @Override
- protected void renderMergedOutputModel(Map
model, HttpServletRequest request, HttpServletResponse response) throws Exception { - System.out.println("自定义视图---调用了MyView的renderMergedOutputModel方法");
- String url = "/WEB-INF/pages/success.jsp";
- request.getRequestDispatcher(url).forward(request, response);
- }
- }
配置自定义视图的解析器,设置其优先级,通过order设置,默认是Integer.MAX_VALUE,值越小,优先级越高。

上面就是该类的主要注释,可以发现该类就是用来解析自定义视图的
- <bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
- <property name="order" value="99"/>
- bean>
然后创建handler进行测试,我们直接返回视图的id即可,id就是直接的视图在spribg容器中的名称
- @RequestMapping("f4")
- public String f4() {
- System.out.println("f4.....");
- return "myView";
- }
访问该handler,自定义视图没有问题


可以发现,使用十分简单,下面就开始debug源码,看底层是如何实现的。
如果不知道底层原理,那么出现bug时就很难解决了,下面就开始debug吧。先debug自定义视图部分



进入该方法,发现就是判断我们是否设置了返回的视图,继续往下执行



进入解析视图方法,查看如何实现的

下面就是所有的解析器

进入自定义视图的resolveViewName

到这里,自定义视图就debug完成了,下面开始默认视图的
debug前面部分都是相同的,下面从遍历所有解析器开始debug


请求的是f1方法,会返回success的视图名称,下面就是自定义视图先进行解析,因为优先级更高

然后就是默认视图解析,我们进行默认视图的resolveViewName方法


由于我们返回的值不是redirect和forward,会继续调用父类的createView方法,一直往里面追,直到看见构建最终的视图url


到这里,默认视图的debug也完成了
自定义视图还是比较简单的,容易理解,为了加深理解,可以自己进行debug