SpringMVC的各种视图 |SprinMVC
SpringMVC中的视图是View接口,视图的作用是渲染数据,将Model模型中的数据展示给用户。
- SpringMVC中的常见的视图有:
①转发视图InternalResourceView
(如果工程工程引入了JSTL依赖,转发视图会自动转换为JSTLView
)
②重定向视图RedirectView
③如果使用的视图技术为Thymeleaf,那么由Thymeleaf视图解析器解析得到的就是ThymeleafView
。
一、ThymeleafView
如果项目中要使用Thymeleaf作为视图解析技术,并且引入了视图解析器ThymeleafViewResolver,那么项目中创建的就是ThymeleafView
。
若控制器方法中所返回的视图名称没有任何前缀,则这个视图名称会被ThymeleafViewResolver拼接视图前缀prefix和视图后缀suffix得到一个
逻辑视图
,这个逻辑视图会通过转发的方式实现跳转
。
@RequestMapping("/testHello")
public String testThymeleafView(){
return "hello";
}
在源码中,通过1061行调用控制器方法执行,执行后返回模型数据mv。再通过1078行处理模型数据mv,到1139行渲染视图。1372行解析视图名称为Thymeleaf获取视图对象。
二、转发视图InternalResourceView
SpringMVC中默认的转发视图就是InternalResourceView。
当控制器方法返回的视图名称以 “forward:” 为前缀时,会创建InternalResourceView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀 “forward:” 去掉,剩余部分作为最终路径通过转发的方式实现跳转。
- 例如:视图名称
"forward:/employee"
被解析时,不会通过SpringMVC的配置文件中的视图解析器拼串,而是通过InternalResourceView将forward:前缀去掉,最终路径变成"employee"
@RequestMapping("/testForward")
public String testInternalResourceView(){
return "forward:/testHello";
}
使用转发还可以将请求转发到同一个应用内的其他页面: return "forward:/WEB-INF/templates/xxx.html";
三、重定向视图RedirectView
SpringMVC中默认的重定向视图是RedirectView
当控制器方法中返回的视图名称以"redirect:"为前缀时,会创建RedirectView视图,此时的视图名称不会被SpringMVC配置文件中所配置的视图解析器解析,而是会将前缀 “redirect:” 去掉,剩余部分作为最终路径通过重定向的方式实现跳转。
- 使用原生的servlet执行重定向,路径需要手动加上项目名;使用SpringMVC则会自动为路径拼接项目名。
- 例如:视图名称
"redirect:/employee"
被解析时,不会通过SpringMVC的配置文件中的视图解析器拼串,而是通过InternalResourceView将forward:前缀去掉,最终路径变成"employee"
@RequestMapping("/testRedirect")
public String testRedirect(){
return "redirect:/testHello";
}
四、视图控制器view-controller
视图控制器view-controller:仅仅是用来
实现页面跳转
。
- path:设置处理的请求地址
- view-name:设置请求地址所对应的视图名称
<mvc:view-controller path="/testView" view-name="success"></mvc:view-controller
注意:当SpringMVC中设置任何一个view-controller时,其他控制器中的请求映射将全部失效,此时需要开启mvc注解驱动才能解决这一问题。
<mvc:annotation-driven />
扩展知识:
一、理解视图解析器
视图解析器只是为了得到视图对象,视图对象才是真正的渲染视图,执行转发或重定向到页面。(会将模型数据全部放在请求域中)
1.SpringMVC解析视图的步骤
- ①无论方法返回什么类型,SpringMVC都会在内部将其装配为
ModelAndView
。 - ②SpringMVC借助视图解析器
(ViewResolver)
得到视图对象(View
)。 - ③视图对象(
View
)真正的渲染页面。
不同的视图解析器具有不同的视图对象,不同的视图对象具有不同的功能(InternalResourceView具有转发的功能,RedirectView具有重定向功能。
)
对于最终究竟采取何种视图对象模型数据进行渲染,处理器并不关心,处理器工作的重点聚焦在生产模型数据的工作上,从而实现MVC的充分解耦。
2.视图
-
作用:渲染模型数据,将模型中的数据以某种形式呈现给用户。
-
为了实现视图模型和具体实现技术的解耦,Spring在org.springframework.web.servlet中定义了一个高度抽象的View接口。
-
视图对象由视图解析器负责实例化。由于视图是无状态(上一次和下一次没关系)的,所以不会有线程安全问题。
2.1常用的视图实现类
2.2常用的视图解析器实现类
四、jstlView支持便捷的国际化
首先需要先导入jstl的jar包:
更改视图解析器
- 指定视图类型为ViewClass,并配置一个资源文件管理器messageSource。
- 资源文件管理器的id必须叫
messageSource
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
<!-- 指定视图类型<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property> -->
</bean>
<!-- 让SpringMVC管理国际化资源文件:配置一个资源文件管理器-->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="i18n"></property>
</bean>
登录页面
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt"%>
导入fmt。- 直接在页面
<fmt:message />
取值。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>
<fmt:message key="welcomeinfo"/>
</h1>
<form action="">
<fmt:message key="username" />:<input/><br/>
<fmt:message key="password" />:<input/><br/>
<input type="submit" value='<fmt:message key="loginBtn"/>'/>
</form>
</body>
</html>
中/英 国际化
i18n_zh_CN.properties(中文)
welcomeinfo=欢迎
username=用户名
password=密码
loginBtn=登录
-------------------------
i18n_en_US.properties(英文)
welcomeinfo=WELCOME
username=USERNAME
password=PASSWORD
loginBtn=LOGIN
国际化一定要过SpringMVC的视图解析流程,在其中会创建一个jstlView帮助快速国际化;controller中不能写forward转发前缀。
view-controller请求映射
如果想发送一个请求,直接来到login页面,不经过controller也是可以的。可以在SpringMVC的配置文件中,配置view-controller请求映射。此时是经过了SpringMVC的视图解析流程且可以国际化。
<!-- 发送toLoginPage请求,直接来到WEB-INF下的login页面 -->
<mvc:view-controller path="/toLoginPage" view-name="login"/>
<!-- 开启MVC注解驱动模式,可以防止屏蔽掉其他动态请求 -->
<mvc:annotation-driven></mvc:annotation-driven>
五、扩展:自定义视图和视图解析器
- 视图解析器根据方法的返回值得到视图对象。
- 如果有多个视图解析器,每个视图解析器都会尝试能否得到视图对象。
- 视图对象不同就可以有不同的功能。
- 现在自定义一个视图和视图解析器:自定义的视图解析器进行工作,得到我们的视图对象,该视图对象自定义渲染逻辑。
1.编写自定义的视图解析器和视图
1.1 自定义视图解析器MyImgViewResolver
public class MyImgViewResolver implements ViewResolver, Ordered {
private Integer order = 0;
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
// TODO Auto-generated method stub
// 根据视图名,返回视图对象
if (viewName.startsWith("img:")) {
return new MyView();
} else {
return null;
}
}
@Override
public int getOrder() {
// TODO Auto-generated method stub
return order;
}
public void setOrder(Integer order) {
this.order = order;
}
}
1.2 自定义视图MyView
public class MyView implements View {
@Override
public String getContentType() {
return "text/html";
}
@Override
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
throws Exception {
System.out.println("之前保存的数据" + model);
response.setContentType("text/html");
List<String> vn = (List<String>) model.get("video");
response.getWriter().write("<h1>正在下载中....</h1>");
for (String string : vn) {
response.getWriter().write("<a>下载" + string + ".avi</a><br/>");
}
List<String> img = (List<String>) model.get("imgs");
for (String string : img) {
response.getWriter().write("<a>下载" + string + ".jpg</a><br/>");
}
}
}
2.视图解析器放入IoC
<!-- 自定义视图解析器加入IoC -->
<bean class="com.gql.view.MyImgViewResolver"></bean>
3.控制器handler
@Controller
public class MyViewResovlerController {
@RequestMapping("/handleplus")
public String handleplus(Model model) {
List<String> vname = new ArrayList<String>();
List<String> imgname = new ArrayList<String>();
model.addAttribute("video", vname);
model.addAttribute("imgs", imgname);
vname.add("冬雨");
vname.add("大力");
imgname.add("双笙");
return "img:figure";
}
}
访问后的界面如下: