SpringMVC框架 |视图解析


一、使用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";
	}
}

访问后的界面如下:
在这里插入图片描述

发布了456 篇原创文章 · 获赞 1472 · 访问量 50万+

猜你喜欢

转载自blog.csdn.net/weixin_43691058/article/details/105407480