SpringMVC的InternalResourceViewResolver视图解析器
SpringMVC的InternalResourceViewResolver视图解析器
我们最常使用的视图解析器就是InternalResourceViewResolver,但是它只是springMVC众多视图解析器中的一个,这篇文章详细介绍了各种解析器,
对于InternalResourceViewResolver的原理,原文是这样说的:
InternalResourceViewResolver会把返回的视图名称都解析为InternalResourceView对象,InternalResourceView会把Controller处理器方法返回的模型属性都存放到对应的request属性中,然后通过RequestDispatcher在服务器端把请求forword重定向到目标URL。比如在InternalResourceViewResolver中定义了prefix=/WEB-INF/,suffix=.jsp,然后请求的Controller处理器方法返回的视图名称为test,那么这个时候InternalResourceViewResolver就会把test解析为一个InternalResourceView对象,先把返回的模型属性都存放到对应的HttpServletRequest属性中,然后利用RequestDispatcher在服务器端把请求forword到/WEB-INF/test.jsp。这就是InternalResourceViewResolver一个非常重要的特性,我们都知道存放在/WEB-INF/下面的内容是不能直接通过request请求的方式请求到的,为了安全性考虑,我们通常会把jsp文件放在WEB-INF目录下,而InternalResourceView在服务器端跳转的方式可以很好的解决这个问题。
意思是什么呢,结合springMVC的工作流程,我们可以更清楚的理解:
当我们对 SpringMVC 控制的资源发起请求时(不是所有的资源都是由SpringMVC控制的,像静态资源就可以通过配置由Tomcat的default servlet处理,也可以使用mvc:resources直接由springMVC框架处理,然后前端控制器dispatcherServlet的url-pattern配置为/的时候会处理除jsp请求之外的请求,jsp请求是由tomcat的JspServlet控制的),这些请求都会被 SpringMVC 的 DispatcherServlet 处理,接着 spring 会分析看哪一个 HandlerMapping 定义的所有请求映射中存在对该请求的最合理的映射。然后通过该 HandlerMapping 取得其对应的 Handler,接着再通过相应的 HandlerAdapter 处理该 Handler。HandlerAdapter 在对 Handler 进行处理之后会返回一个 ModelAndView 对象。在获得了 ModelAndView 对象之后,Spring 就需要把该 View 渲染给用户,即返回给浏览器。在这个渲染的过程中,发挥作用的就是 ViewResolver 和 View。当 Handler 返回的 ModelAndView 中不包含真正的视图,只返回一个逻辑视图名称的时候,ViewResolver 就会把该逻辑视图名称解析为真正的视图 View 对象。View 是真正进行视图渲染,把结果返回给浏览器的。
也就是说,我们的前端控制器在获得了一个资源请求(一般就是servlet,其他的都有其他的解析器解析),它会取出对应的Handler(还记得我们在Controller中使用@RequestMapping()进行注解的内容了吗,它就是为了建立这个映射,而且因为方法和类都有@RequestMapping()注解,最后取得的Handler是一个方法,它经常是这样子的:
package com.jiading.controller;
import com.jiading.domain.Account;
import com.jiading.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* 帐户web
*/
@Controller//这个Controller是给Spring看的,因为我们在Spring的配置文件中配置了它不要带有org.springframework.stereotype.Controller注解的类
@RequestMapping("/account")
public class AccountController {
@Autowired
private AccountService accountService;
@RequestMapping("/findAll")
/**
* 在许多实际项目需求中,后台要从控制层直接返回前端所需的数据,这时Model大家族就派上用场了。
* Model是一个接口,它的实现类为ExtendedModelMap,继承ModelMap类
* spring自动为Model创建实例,并作为controller的入参
*/
public String findAll(Model model){
System.out.println("表现层:查询所有账户...");
// 调用service的方法
List<Account> list = accountService.findAll();
model.addAttribute("list",list);
return "list";
}
}
这里的 return "list";就是返回逻辑视图的名称,视图解析器使用这个名称,再带上我们在视图解析器中配置的suffix(suffix是后缀的意思),就得到了完整的视图名称,再将请求forword到/WEB-INF这个对外部来说不能直接请求的目录下的该资源(这里必须用forward而不能用redirect,因为/WEB-INF这个目录对于外部是不可见的,使用redirect、让浏览器再次发送请求的话,还是得不到)

浙公网安备 33010602011771号