springMVC4(14)各类视图输出实例分析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: <div class="markdown_views"><h1 id="1-模板视图">1. 模板视图</h1><p>FreeMarkerViewResolver 、 VolocityViewResolver 这两个视图解析器都是 UrlBasedViewResolver 的子类。 FreeMarkerViewResolver 会把 Controller 处理方法返回的逻

1. 模板视图

FreeMarkerViewResolver 、 VolocityViewResolver 这两个视图解析器都是 UrlBasedViewResolver 的子类。 FreeMarkerViewResolver 会把 Controller 处理方法返回的逻辑视图解析为 FreeMarkerView ,而 VolocityViewResolver 会把返回的逻辑视图解析为 VolocityView 。这两个视图解析器是类似的。
对于 FreeMarkerViewResolver 而言,它会按照 UrlBasedViewResolver 拼接 URL 的方式进行视图路径的解析。但是使用 FreeMarkerViewResolver 的时候不需要我们指定其 viewClass ,因为 FreeMarkerViewResolver 中已经把 viewClass 默认指定为 FreeMarkerView 了。
对于 FreeMarkerView 我们需要给定一个 FreeMarkerConfig 的 bean 对象来定义 FreeMarker 的配置信息。 FreeMarkerConfig 是一个接口, Spring 已经为我们提供了一个实现,它就是 FreeMarkerConfigurer 。我们可以通过在 SpringMVC 的配置文件里面定义该 bean 对象来定义 FreeMarker 的配置信息。当 FreeMarker 的模板文件放在多个不同的路径下面的时候,我们可以使用 templateLoaderPaths 属性来指定多个路径。
下面我们来看一个使用FreeMaker的实例:
在使用FreeMaker前需要导入相关的jar包,使用Maven可在pom.xml下添加如下信息:

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.24-incubating</version>
</dependency>

在spring容器中配置视图解析器

<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
   <property name="prefix" value="fm_"/><!-- 指定文件前缀 -->
   <property name="suffix" value=".ftl"/><!-- 指定文件后缀 -->
   <property name="order" value="1"/><!-- 指定当前视图解析器的优先级 -->
   <property name="contentType" value="text/html; charset=utf-8" /><!-- 指定编码类型输出,防止出现中文乱码现象 -->
</bean>
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
   <property name="templateLoaderPath" value="/WEB-INF/freeMaker"/><!-- 指定模板文件存放位置 -->
   <property name="defaultEncoding" value="UTF-8" /><!-- 由于模板文件中使用utf-8编码,如果不显式指定,会采用系统默认编码,易造成乱码 -->
   <property name="freemarkerSettings"><!-- 定义FreeMaker丰富的自定义属性 -->
    <props>
        <prop key="classic_compatible">true</prop><!--  当碰到对象属性为null时,返回一个空字符串而非抛出系统异常 -->
    </props>
   </property>
</bean>

接下来我们定义如下一个 Controller :

@Controller
public class MyController {

    @RequestMapping("test")
    public ModelAndView test() {
       mav.addObject("hello", "hello World!");
       mav.setViewName("freemarker");
       return mav;
    }

}

接下来在/WEB-INF/freeMaker目录下创建一个名为fm_hello.ftl的模板文件,内容如下:

<html>
    <head>
       <title>FreeMarker</title>
    </head>
    <body>
       ${hello}
    </body>
</html>

经过上面的定义当我们访问 /freemarker 的时候就会返回一个逻辑视图名称为“hello”的 ModelAndView 对象,根据定义好的视图解析的顺序,首先进行视图解析的是 FreeMarkerViewResolver ,这个时候 FreeMarkerViewResolver 会试着解析该视图,根据它自身的定义,它会先解析到该视图的 URL 为 fm_freemarker.ftl ,然后它会看是否能够实例化该视图对象,即在定义好的模板路径下是否有该模板存在,如果有则返回该模板对应的 FreeMarkerView。在本例中访问结果如下所示:

hello World!

2. JSON视图输出

我们可以使用BeanNameViewResolver来输出JSON视图,spring配置文件如下所示:

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" >
    <property name="order" value="1"/>
</bean>
<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" id="userJson"><!--指定json视图类型-->
    <property name="modelKey" value="map" />
    <!--实际开发中在控制器我们可能会有很多模型数据,
    这里通过modelKey指定只输出名为user的模型数据-->
    <!--如果我们想指定多个模型数据输出,可以使用modelKeys,它是一个Set集合,
    实例配置如下:
        <property name="modelKeys">
            <set >
                <value>name1</value>
                <value>name2</value>
            </set>
        </property>
    -->
</bean>

指定使用此视图输出后,我们编写我们的控制器输出一个Map来测试视图

@RequestMapping("jsonView")
public String jsonView(ModelMap map ){
    for(int i = 0 ; i < 5; i ++){
        map.put("key" + i," value" + i);
    }
    return "userJson";//对应json视图的Bean名
}

访问jsonView,输出视图如下,注意箭头部分,我们的相应Content-Type变为了application/json,这也是json视图输出的特点
这里写图片描述

3. XML视图输出

我们使用spring-oxm来完成我们java对象到xml格式文本的转换,需先导入相关的jar包,使用maven可在pom.xml上添加:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-oxm</artifactId>
    <version>4.1.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.thoughtworks.xstream</groupId>
    <artifactId>xstream</artifactId>
    <version>1.4.9</version>
</dependency>

我们使用MarshallingView来输出xml视图,还是使用BeanNameViewResolver来解析xml视图,它的配置如下所示:

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean class="org.springframework.web.servlet.view.xml.MarshallingView" id="myXmlView">
    <property name="modelKey" value="articles"/><!--输出模型中的articles属性-->
    <property name="marshaller" ref="xmlMarshaller" /><!--指定解析工具-->
</bean>
<bean class="org.springframework.oxm.xstream.XStreamMarshaller" id="xmlMarshaller"><!-- 将模型数据转换为XML格式 -->
    <property name="streamDriver">
        <bean class="com.thoughtworks.xstream.io.xml.StaxDriver" />
    </property>
</bean>

下面是我们的Article POJO类和控制层配置:

/*******************POJO类****************/
public class Article {
    private String title;
    private String content;
    //忽略get和set方法
}
/**************控制层拦截方法********************/
@RequestMapping("xmlView")
    public String xmlView(ModelMap map){
        List<Article>articles = new ArrayList<Article>();
        for(int i = 0 ; i < 5; i ++){
            Article article = new Article();
            article.setTitle("title" +i);
            article.setContent("content" + i);
            articles.add(article);
        }
        map.addAttribute("articles",articles);
        return "myXmlView";
    }

我们在游览器上访问xmlView,视图输出如下数据:

<?xml version="1.0" ?>
<list>
    <com.mvc.model.Article>
        <title>title0</title>
        <content>content0</content>
    </com.mvc.model.Article>
    <com.mvc.model.Article>
        <title>title1</title>
        <content>content1</content>
    </com.mvc.model.Article>
    <com.mvc.model.Article>
        <title>title2</title>
        <content>content2</content>
    </com.mvc.model.Article>
    <com.mvc.model.Article>
        <title>title3</title>
        <content>content3</content>
    </com.mvc.model.Article>
    <com.mvc.model.Article>
        <title>title4</title>
        <content>content4</content>
    </com.mvc.model.Article>
</list>

同时相应Content-Type是application/xml;charset=UTF-8

4. 输出excel视图

输出excel视图需要先导入jar包:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.14</version>
</dependency>

excel视图需要拓展AbstractExcelView并实现其抽象方法buildExcelDocument,下面是一个实例配置:

package com.mvc.view;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.web.servlet.view.document.AbstractExcelView;

import com.mvc.model.Article;

public class ExcelView extends AbstractExcelView {

    @Override
    protected void buildExcelDocument(Map<String, Object> model,
            HSSFWorkbook workbook, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
         List<Article> articles= (List<Article>) model.get("articles");

         HSSFSheet sheet = workbook.createSheet("文章列表");//创建一页
         HSSFRow header = sheet.createRow(0);//创建第一行
         header.createCell(0).setCellValue("标题");
         header.createCell(1).setCellValue("正文");
         for( int i = 0; i < articles.size();i++){
             HSSFRow row = sheet.createRow(i + 1);
             Article article = articles.get(i);
             row.createCell(0).setCellValue(article.getTitle());
             row.createCell(1).setCellValue(article.getContent());
         }
    }
}

spring容器配置如下所示:

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean class="com.mvc.view.ExcelView" id="excelView" /><!-- 注册自定义视图 -->

编写控制器:

@RequestMapping("excelView")
public String excelView(ModelMap map){
    List<Article>articles = new ArrayList<Article>();
    for(int i = 0 ; i < 5; i ++){
        Article article = new Article();
        article.setTitle("title" +i);
        article.setContent("content" + i);
        articles.add(article);
    }
    map.addAttribute("articles",articles);
    return "excelView";
}

在游览器访问,则提示下载文件:
这里写图片描述
下载打开显示如下内容:
这里写图片描述

目录
相关文章
|
4月前
|
前端开发 Java Spring
SpringMVC种通过追踪源码查看是哪种类型的视图渲染器(一般流程方法)
这篇文章通过示例代码展示了如何在Spring MVC中编写和注册拦截器,以及如何在拦截器的不同阶段添加业务逻辑。
SpringMVC种通过追踪源码查看是哪种类型的视图渲染器(一般流程方法)
|
4月前
|
设计模式 固态存储 开发者
创建一个仅用一个函数/模块/类就可以处理这组不同事物的抽象
在软件开发中,良好的变量名和函数名能够显著提升代码的可读性和可维护性。对于变量命名,建议使用有意义且易于发音的名字(如 `currentDate` 而非 `yyyymmdstr`),对同类变量使用一致的词汇(如统一使用 `getUser`),以及使用解释性的变量名以减少理解成本(如使用常量 `MILLISECONDS_IN_A_DAY` 替代数字 `86400000`)。此外,避免不必要的上下文重复,并使用默认参数代替逻辑运算。对于函数,应限制参数数量(理想情况下不超过两个),确保每个函数只做一件事,并且函数名应清晰描述其功能。通过遵循这些原则,代码将更加简洁明了。
35 3
|
编译器 C++
C++ :类 和 对象 ※重点※(一)
C++ :类 和 对象 ※重点※
50 0
|
Java 编译器 C++
C++ :类 和 对象 ※重点※(三)
C++ :类 和 对象 ※重点※(三)
86 0
|
编译器 C++
C++ :类 和 对象 ※重点※(二)
C++ :类 和 对象 ※重点※(二)
77 0
|
C++ 计算机视觉 数据格式
C/C++主调函数从被调函数中获取(各种类型)数据内容方式的梳理归纳
C/C++主调函数从被调函数中获取(各种类型)数据内容方式的梳理归纳
230 1
C/C++主调函数从被调函数中获取(各种类型)数据内容方式的梳理归纳
|
Java 容器 Spring
Spring练习,定义三个模块,使用<import>标签完成分模块配置开发,模拟实现学生借书和还书的过程,将结束输出到控制台。
Spring练习,定义三个模块,使用<import>标签完成分模块配置开发,模拟实现学生借书和还书的过程,将结束输出到控制台。
203 0
Spring练习,定义三个模块,使用<import>标签完成分模块配置开发,模拟实现学生借书和还书的过程,将结束输出到控制台。
|
XML API Android开发
[译] 关于视图加载的一些奇技淫巧
[译] 关于视图加载的一些奇技淫巧