springMVC4(15)RestFul多视图混合输出

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: <div class="markdown_views"><p>4# 混合使用多种视图技术。 <br>在前面文章里,我们对jsp、json、xml个中视图都进行了较为详细的实例解析,但涉及到的都是单视图使用配置。在实际开发中,我们可能需要混合是使用多种视图技术。尤其是针对REST编程风格,我们可以通过<strong>一个URL、多种视图</strong>来切合REST风格的<

4# 混合使用多种视图技术。
在前面文章里,我们对jsp、json、xml个中视图都进行了较为详细的实例解析,但涉及到的都是单视图使用配置。在实际开发中,我们可能需要混合是使用多种视图技术。尤其是针对REST编程风格,我们可以通过一个URL、多种视图来切合REST风格的同一资源、多种表述
现在加入我们要输出JSP、JSON、XML多种视图技术,如果使用我之前文章《springMVC4(4)json与对象互转实例解析请求响应数据转换器 》提到的HttpMessageConvert来完成数据类型输出切换。它相对于多视图输出的局限性是:
1. 必须通过HTTP请求头的Accept来控制转换器的使用类型,如果客户端是安卓等还能通过HttpClient、RestTemplate等控制,但如果客户端是游览器,除非使用AJAX技术,否则很难控制请求头内容
2. 无法通过URL扩展名或请求参数来控制服务端的资源输出类型。而使用多种视图技术,我们可以通过以下形式控制输出不同视图:
1. 扩展名:
1. /user.xml 呈现xml文件
2. /user.json 呈现json格式
3. /user.xls 呈现excel文件
4. /user.pdf 呈现pdf文件
5. /user 使用默认view呈现,比如jsp等
2. 请求参数:
1. /user?type=xml 呈现xml文件
2. /user?type=json 呈现json格式
3. /user?type=xls 呈现excel文件
4. /user?type=pdf 呈现pdf文件
5. /user? 使用默认view呈现,比如jsp等

ContentNegotiatingViewResolver

我们使用ContentNegotiatingViewResolver视图解析器来完成多种视图混合解析,从它的名字上看,它是一个视图协调器,负责根据请求信息从当前环境选择一个最合适的解析器进行解析,也即是说,它本身并不负责解析视图。
它有3个关键属性:
1. favorPathExtension:如果设置为true(默认为true),则根据URL中的文件拓展名来确定MIME类型
2. favorPathExtension:如果设置为true(默认为false),可以指定一个请求参数确定MIME类型,默认的请求参数为format,可以通过parameterName属性指定一个自定义属性。
3. ignoreAcceptHeader(默认为false),则采用Accept请求报文头的值确定MIME类型。由于不同游览器产生的Accept头不一致,不建议采用Accept确定MIME类型。
在实际流程中,ContentNegotiatingViewResolver也是根据以上三个互斥属性的配置情况来确定视图类型,其中属性1优先级最高,属性3优先级最低

除了以上三个属性,还有一个关键属性是mediaTypes,用来配置不同拓展名或参数值映射到不同的MIME类型
在前面,我们展示了使用jsp/模板、json、xml、Excel等来呈现我们的视图,下面我们通过整合上述视图来分析我们的多视图混合技术

多视图混合Rest呈现实例

1. 配置视图解析器

<!-- 根据确定出的不同MIME名,使用不同视图解析器解析视图 -->
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <!-- 设置优先级 -->
    <property name="order" value="1" />
    <!-- 设置默认的MIME类型,如果没有指定拓展名或请求参数,则使用此默认MIME类型解析视图 -->
    <property name="defaultContentType" value="text/html" />
    <!-- 是否不适用请求头确定MIME类型 -->
    <property name="ignoreAcceptHeader" value="true" />
     <!-- 是否根据路径拓展名确定MIME类型 -->
    <property name="favorPathExtension" value="false" />
   <!-- 是否使用参数来确定MIME类型 -->
    <property name="favorParameter" value="true" /> 
    <!-- 上一个属性配置为true,我们指定type请求参数判断MIME类型 -->
    <property name="parameterName" value="type" />
    <!-- 根据请求参数或拓展名映射到相应的MIME类型 -->
    <property name="mediaTypes">
        <map>
            <entry key="html" value="text/html" />
            <entry key="xml" value="application/xml" />
            <entry key="json" value="application/json" />
            <entry key="excel" value="application/vnd.ms-excel"></entry>
        </map>
    </property>
    <!-- 设置默认的候选视图,如果有合适的MIME类型,将优先从以下选择视图,找不到再在整个Spring容器里寻找已注册的合适视图 -->
    <property name="defaultViews">
        <list>
            <bean class="org.springframework.web.servlet.view.InternalResourceView">
                <property name="url" value="WEB-INF/views/hello.jsp"></property>
            </bean>
            <bean
                class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
            <ref local="myXmlView" />
            <bean class="com.mvc.view.ExcelView" />

        </list>
    </property>
</bean>
<!-- Excel视图 -->
<bean class="com.mvc.view.ExcelView" id="excelView" /><!-- 注册自定义视图 -->
<bean class="org.springframework.web.servlet.view.xml.MarshallingView"
    id="myXmlView">
    <property name="modelKey" value="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>

关于以上视图文件的配置实体讲解可移步参考我前面的文章

2. jsp视图文件

<%@page import="com.mvc.model.Article"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>hello spring mvc</title>
  </head>
  <body>
  <c:out value="${articles}"></c:out>
  </body>
</html>

3. Excel配置文件

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());
         }
    }

}

4. Article POJO类

package com.mvc.model;

public class Article {
    private String title;
    private String content;

    //忽略get和set方法
    @Override
    public String toString() {
        return "Article [ title=" + title + ", content="
                + content + "]";
    }

}

5. 控制器测试方法

@RequestMapping("views")
public String views(ModelMap map,HttpServletRequest request){
    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 "views";
}

6. 进行测试

我们使用了参数type来映射不同的视图类型:

1. 默认参数类型:

这里写图片描述

2. html参数类型

这里写图片描述

3. json参数类型

这里写图片描述

4. xml参数类型

这里写图片描述

5. excel参数类型

这里写图片描述
点击下载后打开如下图所示:
这里写图片描述

7. 使用拓展名类型

上面我们使用参数的方法访问,如果我们改成使用拓展名的形式,如下所示,只需去掉其中的4行配置:

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"><!-- 根据确定出的不同MIME名,使用不同视图解析器解析视图 -->
    <property name="order" value="1" /><!-- 设置优先级 -->
    <property name="defaultContentType" value="text/html" /><!-- 设置默认的MIME类型,如果没有指定拓展名或请求参数,则使用此默认MIME类型解析视图 -->
    <property name="mediaTypes"><!-- 根据请求参数映射到相应的MIME类型 -->
        <map>
            <entry key="html" value="text/html" />
            <entry key="xml" value="application/xml" />
            <entry key="json" value="application/json" />
            <entry key="excel" value="application/vnd.ms-excel"></entry>
        </map>
    </property>
    <property name="defaultViews"><!-- 设置默认的候选视图,如果有合适的MIME类型,将优先从以下选择视图,找不到再在整个Spring容器里寻找已注册的合适视图 -->
        <list>
            <bean class="org.springframework.web.servlet.view.InternalResourceView">
                <property name="url" value="WEB-INF/views/hello.jsp"></property>
            </bean>
            <bean
                class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
            <ref local="myXmlView" />
            <bean class="com.mvc.view.ExcelView" />
        </list>
    </property>
</bean>

这个时候,我们就可以使用:
http://localhost:8080/springMVC/views
http://localhost:8080/springMVC/views.html,
http://localhost:8080/springMVC/views.json
http://localhost:8080/springMVC/views.xml
来对应得到与上面相同的内容。感兴趣的朋友可在下面下载源码自行测试

源码下载

本节内容源码可到http://github.com/jeanhao/spring的multiViews文件夹下下载

目录
相关文章
|
5天前
|
设计模式 前端开发 Java
步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理
通过对 `DispatcherServlet`源码的深入剖析,我们了解了SpringMVC请求处理的全流程。`DispatcherServlet`作为前端控制器,负责请求的接收和分发,处理器映射和适配负责将请求分派到具体的处理器方法,视图解析器负责生成和渲染视图。理解这些核心组件及其交互原理,有助于开发者更好地使用和扩展SpringMVC框架。
22 4
|
23天前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
68 2
|
2月前
|
JSON 前端开发 Java
SSM:SpringMVC
本文介绍了SpringMVC的依赖配置、请求参数处理、注解开发、JSON处理、拦截器、文件上传下载以及相关注意事项。首先,需要在`pom.xml`中添加必要的依赖,包括Servlet、JSTL、Spring Web MVC等。接着,在`web.xml`中配置DispatcherServlet,并设置Spring MVC的相关配置,如组件扫描、默认Servlet处理器等。然后,通过`@RequestMapping`等注解处理请求参数,使用`@ResponseBody`返回JSON数据。此外,还介绍了如何创建和配置拦截器、文件上传下载的功能,并强调了JSP文件的放置位置,避免404错误。
|
2月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
64 2
|
3月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
2月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
176 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
3月前
|
XML 缓存 前端开发
springMVC02,restful风格,请求转发和重定向
文章介绍了RESTful风格的基本概念和特点,并展示了如何使用SpringMVC实现RESTful风格的请求处理。同时,文章还讨论了SpringMVC中的请求转发和重定向的实现方式,并通过具体代码示例进行了说明。
springMVC02,restful风格,请求转发和重定向
|
4月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
4月前
|
XML JSON 数据库
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
这篇文章详细介绍了RESTful的概念、实现方式,以及如何在SpringMVC中使用HiddenHttpMethodFilter来处理PUT和DELETE请求,并通过具体代码案例分析了RESTful的使用。
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
|
4月前
|
前端开发 应用服务中间件 数据库
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
这篇文章通过一个具体的项目案例,详细讲解了如何使用SpringMVC、Thymeleaf、Bootstrap以及RESTful风格接口来实现员工信息的增删改查功能。文章提供了项目结构、配置文件、控制器、数据访问对象、实体类和前端页面的完整源码,并展示了实现效果的截图。项目的目的是锻炼使用RESTful风格的接口开发,虽然数据是假数据并未连接数据库,但提供了一个很好的实践机会。文章最后强调了这一章节主要是为了练习RESTful,其他方面暂不考虑。
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
下一篇
DataWorks