后端——框架——视图层框架——spring mvc——View & ViewResolver
涉及到视图的有两个核心对象,View,ViewResolver。
View表示一种特定的视图类型,ViewResolver则表示视图解析器,类似于事件与事件handler之间的关系。
View大体分为四种类型
- 第一种,字符串,此时需要ViewResolver进行解析,不同的ViewResolver会返回不同类型的View。例如JSP页面。
- 第二种,特定格式数据类型,最常见的有JSON,XML。
- 第三种,二进制流,由于PDF,Excel较为常见,mvc内置有PdfView和ExcelView。
- 第四种,重定向,"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(Mapmodel, 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
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对象的类型与具体的子类有关。它有以下几个子类。
- ScriptTemplateViewResolver:未使用过,待补充
- InternalResourceViewResolver:最常用的一种方式,View对应具体的静态资源(JSP,HTML页面)
- FreeMarkerViewResolver:FreeMarker框架的模板,未使用过,待补充。
- GroovyMarkupViewResolver:未使用过,待补充
- TilesViewResolver:Apache Tiles框架的模板。未使用过,待补充
- 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对象消息体中的内容。