后端——框架——视图层框架——spring mvc——View & ViewResolver


  涉及到视图的有两个核心对象,View,ViewResolver。

  View表示一种特定的视图类型,ViewResolver则表示视图解析器,类似于事件与事件handler之间的关系。

  View大体分为四种类型

  1. 第一种,字符串,此时需要ViewResolver进行解析,不同的ViewResolver会返回不同类型的View。例如JSP页面。
  2. 第二种,特定格式数据类型,最常见的有JSON,XML。
  3. 第三种,二进制流,由于PDF,Excel较为常见,mvc内置有PdfView和ExcelView。
  4. 第四种,重定向,"redirect:XX","forward:XX"。

1、类图

1.1   viewResolver

它是顶层接口,只有resolverViewName一个方法。它的功能是将视图的名称转换为视图对象。

参数:String viewName(视图名称),Locale locale(国际化信息)。

返回值:View,它是视图对象的顶层类(root)。

1.2    BeanName

它是建立视图名称与View对象之间的关系。此时handler方法的返回值为视图名称,同时也是View对象的唯一标识(beanID)。

步骤如下:

第一步,创建View对象,并注入。

public class MyView implements View {
	@Override
	public String getContentType() {
		return "text/html";
	}
	@Override
	public void render(Map model, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		response.setContentType(getContentType());
		response.setCharacterEncoding("UTF-8");
		PrintWriter writer = response.getWriter();
		writer.println("

测试BeanNameViewResolver

"); } }

  第二步,注册BeanNameViewResolver对象

@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
	// 注册BeanNameViewResolver
	registry.beanName();
}

  第三步,验证,根据handler方法的返回值找View对象。示例中bean名称为myView,任意的handler方法返回myView,即会返回”测试BeanNameViewResolver”。

1.3  contentNegotiating

  根据请求内容的类型选择最优的视图解析器。

ContentNegotiationManager用于管理请求内容的类型。View对象自身包含处理特定类型的请求内容。

它有两个属性。

defaultView,当无法找到合适的View对象时,使用defaultView。

useNotAcceptableStatusCode,当无法找到合适的View对象且未设置defaultView时,设置为false,抛出异常。设置为true,返回NON_ACCEPTABLE_VIEW。

注册:

@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
	// 注册ContentNegotiatingViewResolver
	registry.enableContentNegotiation(false,new MyView());
}

1.4    viewResolverComposite

  包含List字段,管理视图解析器。根据请求的内容在集合中查找视图解析器,并根据该解析器查找对应的View对象,若找到,则成功。若未找到,则失败。

1.5    abstractCaching

  顶层接口,提供了缓存功能,设置缓存大小,清空缓存,获取,添加等。

  1.5.1   xml

  与beanNameViewResolver原理相同,区别在于是通过特定的配置文件(views.xml)建立视图名称与View对象之间的关系。

  步骤如下:

  第一步,创建XmlViewResolver, 并注册

private XmlViewResolver getXmlViewResolver() {
	// 创建XmlViewResolver对象
	XmlViewResolver xmlView = new XmlViewResolver();
	// 创建resource对象
	Resource resource =  new ClassPathResource("/spring/mvc/views.xml");
	// 设置地址
	xmlView.setLocation(resource);
	return xmlView;
}
// 注册
registry.viewResolver(getXmlViewResolver());

  第二步,编写View对象,以及views.xml。

<?xml version="1.0" encoding="UTF-8"?>

	

  第三步,验证, handler方法返回error,则会返回MyView对象。

1.5.2    resourceBundle

  与xmlViewResolver原理相同,区别在于使用properties文件建立视图名称与View对象的关系。

properties文件的格式为:

viewname.(class)=ViewClassName,其中viewname表示handler方法的返回值,viewClassName为类全名。

viewname.url=requestUrl,其中viewname表示handler方法的返回值,requestUrl表示请求的URL地址,若是静态资源,值为静态资源的路径。

  步骤如下

  第一步,创建ResourceBundlerViewResolver并注册。

private ResourceBundleViewResolver getResourceBundleViewResolver() {
	// 创建ResourceBundleViewResolver对象
	ResourceBundleViewResolver resourceView = new ResourceBundleViewResolver();
	// 设置优先级
	resourceView.setOrder(Integer.MIN_VALUE);
	// 设置base_name
	resourceView.setBasename("spring/mvc/views");
	return resourceView;
}
// 注册ResourceBundleViewResolver
registry.viewResolver(getResourceBundleViewResolver());

  spring/mvc/views表示spring/mvc路径下的views.properties文件。

  第二步,编写View对象,views.properties文件。

# 配置
test.(class)=viewResolver.MyView

  第三步,验证。

1.5.3 UrlBased

  UrlBasedViewResolver在解析视图的过程中将viewname视为url地址,至于View对象的类型与具体的子类有关。它有以下几个子类。

  1. ScriptTemplateViewResolver:未使用过,待补充
  2. InternalResourceViewResolver:最常用的一种方式,View对应具体的静态资源(JSP,HTML页面)
  3. FreeMarkerViewResolver:FreeMarker框架的模板,未使用过,待补充。
  4. GroovyMarkupViewResolver:未使用过,待补充
  5. TilesViewResolver:Apache Tiles框架的模板。未使用过,待补充
  6. XsltViewResolver:xstl框架的模板。未使用过,待补充。

  方法返回url,通常有两种,”redirect:url”; “forward:url”

  1.5.3.1   InternalResource

建立viewName与静态资源的关系。

步骤如下:

第一步,创建InternalResourceViewResolver并注册。

private InternalResourceViewResolver getInternalResourceViewResolver() {
	// 创建InternalResourceViewResolver对象
	InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
	// 设置响应的类型,JSP的content-type类型为text/html
	viewResolver.setContentType("text/html");
	// 配置JSP存放的根目录
	viewResolver.setPrefix("/WEB-INF/view/");
	// 配置JSP的后缀
	viewResolver.setSuffix(".jsp");
	return viewResolver;
}

  第二步,编写对应的jsp或html页面,略。

  第三步,验证。返回test字符串,会返回WEB-INF/view/test.jsp的内容

  1.5.3.2   freeMarker

  建立viewName与freeMarker模板的关系。

  步骤如下:

  第一步,创建并注册。 

@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
	// 创建FreeMarkerConfigurer
	FreeMarkerConfigurer configure = new FreeMarkerConfigurer();
	// 设置template的路径
	configure.setTemplateLoaderPath("/WEB-INF/view/freemarker/");
	return configure;
}
// FreeMarkerViewResolver对象。
registry.freeMarker();

  第二步,编写freemarker模板。

  第三步,验证。

  1.5.3.3    groovyMarker

  与freemarker基本一致,区别在于模板不同,启用调用的方法不同。

  1.5.3.4    scriptView & TilesView

  不常见,略。

2、 PDF & Excel

  PDF和Excel是View对象的类型,它不是视图处理器。

使用步骤如下:

  第一步,引入相关jar包


	com.lowagie
	itext
	2.1.7


	com.itextpdf
	itextpdf
	5.5.9

  第二步,编写类,实现AbstractPdfView或AbstractExcelView。

  第三步,注册。

registry.enableContentNegotiation(new PdfView());

  第四步,验证,编写handler方法,返回MyPdfView或MyExcelView对象。

3、JSON

  当响应内容为JSON字符串时。有两个核心点。

设置produce=application json。 添加@Responsebody注解。

当返回值为String类型时,此时编写程序手动将其转换为JSON字符串即可。

当返回值为对象时,mvc内置Jackson, 将对象转换字符串。

4、XML

  当响应内容为XML时,核心点与JSON相同,区别在于使用的技术不同。

步骤如下:

第一步,在普通的JavaBean上添加J2XB的相关注解。

@XmlRootElement
public class User {
	// 姓名
	private String name;
	// 年龄
	private int age;
    // getter & setter 略
}

  第二步,handler方法返回MarshallingView。

@GetMapping("/xml")
public MarshallingView getUserByXml(@ModelAttribute User user) {
	Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
	marshaller.setClassesToBeBound(User.class);

	MarshallingView view = new MarshallingView();
	view.setMarshaller(marshaller);
	return view;
}

  第三步,验证,返回结果如下:


	200
	some message
	
		Jack
		10
	

5、重定向

当返回值有前缀”redirect:”时,此时View的类型为RedirectView,视图解析器为UrlBasedViewResolver。redirect后续的字符串为转换请求的URL地址。

当返回值有前缀”forward:”时,此时相当于调用RequestDispatcher.forward方法,后续的字符串为请求的URL地址,也是forward方法的参数。Forward方法会清空response对象消息体中的内容。

相关