文章目录
一、使用forward转发
在Controller中想要访问项目中的某个页面(假设success1配置了视图解析器
),下图为例:
如果要访问success1.jsp
,可以使用下面的方式:
@RequestMapping("/hello")
public String hello() {
return "success1";
}
如果要访问success2.jsp
,则需要使用下面的两种方式:
方式1:命令行写法
- 使用命令行写法默认由视图解析器进行拼串。
@RequestMapping("/hello")
public String hello() {
return "../../success2";
}
方式2:forward写法
使用forward前缀可以指定一个转发操作,此操作独立解析。可以转发到jsp页面,也可以转发到另一个controller请求。
- 使用forward不会由视图解析器进行拼串。
@RequestMapping("/hello")
public String hello() {
return "forward:/success2.jsp";
}
二、使用redirect重定向
原生的Servlet重定向,路径需要手动加上项目名。response.sendRedirect("(项目名)/success2.jsp");
;SpringMVC则会自动为路径拼接项目名,也可以重定向到另一个controller请求。
- 使用redirect不会由视图解析器进行拼串。
@RequestMapping("/handler01")
public String handler01() {
return "redirect:/success2.jsp";
}
视图解析器只是为了得到视图对象,视图对象才能真正的转发(讲模型数据全部放在请求域中)或重定向到页面,即视图对象才能真正的渲染视图。
三、理解视图解析器
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";
}
}
访问后的界面如下: