所谓的视图解析器就是将ViewName或者ModelAndView解析成View视图对象
讲解几个常见的视图解析器:
UrlBasedViewResolver
InternalResourceViewResolver
XmlViewResolver
ResourceBundleViewResolver
BeanNameViewResolver
1. UrlBasedViewResolver和InternalResourceViewResolver
关系:InternalResourceViewResolver是UrlBasedViewResolver的子类
当配置UrlBasedViewResolver解析器时,必须为其指定ViewClass属性,表示解析哪种视图,一般用的最多的是InternalResourceViewResolver,用于呈现普通的JSP视图。
InternalResourceViewResolver的工作原理就是拼接String:指定前缀+逻辑是图名+指定后缀=视图资源位置
配置示例:
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"
p:viewClass="org.springframework.web.servlet.view.InternalResourceView"
p:prefix="WEB-INF/content/" p:suffix=".jsp"
p:exposeContextBeansAsAttributes="true"
p:exposedContextBeanNames="now"/>
prefix:指定前缀
suffix:指定后缀
exposeContextBeansAsAttributes:指定是否暴露Spring容器中的的bean给视图(有时候视图需要获取Spring容器中的bean)
exposedContextBeanNames:指定暴露哪些bean(bean的id)给视图,以逗号隔开,若不配置,则默认暴露所有bean(不明智的做法)
上面的UrlBasedViewResolver也可以直接用InternalResourceView代替,这样就不用配置viewClass了
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="WEB-INF/content/" p:suffix=".jsp"
p:exposeContextBeansAsAttributes="true"
p:exposedContextBeanNames="now"/>
配置好了之后只要在控制器中return逻辑试图名ViewName就可以了,而不用return完整的资源位置
例如:
@PostMapping("/login")
public String login(String username, String password, Model model)
{
if (userService.userLogin(username,password)>0)
{
model.addAllAttributes(Map.of("tip","欢迎您,登入成功!"));
return "success";
}
model.addAllAttributes(Map.of("tip","账号或者密码错误!"));
return "error";
}
经过解析后,得到的是
WEB-INF/content/success.jsp或者WEB-INF/content/error.jsp了
2. XmlViewResolver、ResourceBundleViewResolver、BeanNameViewResolver
2.1
有时候我们不是以jsp作为view而是自定义一个view对象,那么我们就可以用这些视图解析器了。
话不多说,直接上栗子:
<bean class="org.springframework.web.servlet.view.XmlViewResolver"
p:location="/WEB-INF/views.xml"
p:order="1"/>
Location:指定配置视图对象的容器
Order:指定该视图解析器的解析顺序(数字越小,解析器优先级越高)
至于视图对象View,就像普通的bean一样配置就行了。
<bean id="bks" class="com.lyx.app.view.ViewBooks2"/>
这个bks对应于控制器return的String,ViewBooks2是自定义的View
至于视图对象就是指实现了View接口(或者继承了实现了View接口的子类)的java对象,具体写法不展开。
2.2
当然也可以不单独创建View的容器,而是把View配置在其他已经存在的Spring容器中,这时候就可以用BeanNameViewResolver解析器:
示例:
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"
p:order="1"/>
这个时候就不用指定location属性了,bean的配置与前面一直
2.3
除了用Spring配置Bean的风格配置View对象之外还可以用属性文件来配置View
例如:
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver"
p:basename="views"
p:order="1"/>
bks.(class)=com.lyx.app.view.ViewBooks2