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

简介: <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文件夹下下载

目录
相关文章
|
6月前
|
前端开发 Java 测试技术
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestParam
本文介绍了 `@RequestParam` 注解的使用方法及其与 `@PathVariable` 的区别。`@RequestParam` 用于从请求中获取参数值(如 GET 请求的 URL 参数或 POST 请求的表单数据),而 `@PathVariable` 用于从 URL 模板中提取参数。文章通过示例代码详细说明了 `@RequestParam` 的常用属性,如 `required` 和 `defaultValue`,并展示了如何用实体类封装大量表单参数以简化处理流程。最后,结合 Postman 测试工具验证了接口的功能。
334 0
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestParam
|
6月前
|
JSON 前端开发 Java
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestBody
`@RequestBody` 是 Spring 框架中的注解,用于将 HTTP 请求体中的 JSON 数据自动映射为 Java 对象。例如,前端通过 POST 请求发送包含 `username` 和 `password` 的 JSON 数据,后端可通过带有 `@RequestBody` 注解的方法参数接收并处理。此注解适用于传递复杂对象的场景,简化了数据解析过程。与表单提交不同,它主要用于接收 JSON 格式的实体数据。
504 0
|
6月前
|
前端开发 Java 微服务
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@PathVariable
`@PathVariable` 是 Spring Boot 中用于从 URL 中提取参数的注解,支持 RESTful 风格接口开发。例如,通过 `@GetMapping(&quot;/user/{id}&quot;)` 可以将 URL 中的 `{id}` 参数自动映射到方法参数中。若参数名不一致,可通过 `@PathVariable(&quot;自定义名&quot;)` 指定绑定关系。此外,还支持多参数占位符,如 `/user/{id}/{name}`,分别映射到方法中的多个参数。运行项目后,访问指定 URL 即可验证参数是否正确接收。
321 0
|
6月前
|
JSON 前端开发 Java
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestMapping
@RequestMapping 是 Spring MVC 中用于请求地址映射的注解,可作用于类或方法上。类级别定义控制器父路径,方法级别进一步指定处理逻辑。常用属性包括 value(请求地址)、method(请求类型,如 GET/POST 等,默认 GET)和 produces(返回内容类型)。例如:`@RequestMapping(value = &quot;/test&quot;, produces = &quot;application/json; charset=UTF-8&quot;)`。此外,针对不同请求方式还有简化注解,如 @GetMapping、@PostMapping 等。
278 0
|
6月前
|
JSON 前端开发 Java
微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RestController
本文主要介绍 Spring Boot 中 MVC 开发常用的几个注解及其使用方式,包括 `@RestController`、`@RequestMapping`、`@PathVariable`、`@RequestParam` 和 `@RequestBody`。其中重点讲解了 `@RestController` 注解的构成与特点:它是 `@Controller` 和 `@ResponseBody` 的结合体,适用于返回 JSON 数据的场景。文章还指出,在需要模板渲染(如 Thymeleaf)而非前后端分离的情况下,应使用 `@Controller` 而非 `@RestController`
214 0
|
2月前
|
前端开发 Java API
Spring Cloud Gateway Server Web MVC报错“Unsupported transfer encoding: chunked”解决
本文解析了Spring Cloud Gateway中出现“Unsupported transfer encoding: chunked”错误的原因,指出该问题源于Feign依赖的HTTP客户端与服务端的`chunked`传输编码不兼容,并提供了具体的解决方案。通过规范Feign客户端接口的返回类型,可有效避免该异常,提升系统兼容性与稳定性。
189 0
|
2月前
|
SQL Java 数据库连接
Spring、SpringMVC 与 MyBatis 核心知识点解析
我梳理的这些内容,涵盖了 Spring、SpringMVC 和 MyBatis 的核心知识点。 在 Spring 中,我了解到 IOC 是控制反转,把对象控制权交容器;DI 是依赖注入,有三种实现方式。Bean 有五种作用域,单例 bean 的线程安全问题及自动装配方式也清晰了。事务基于数据库和 AOP,有失效场景和七种传播行为。AOP 是面向切面编程,动态代理有 JDK 和 CGLIB 两种。 SpringMVC 的 11 步执行流程我烂熟于心,还有那些常用注解的用法。 MyBatis 里,#{} 和 ${} 的区别很关键,获取主键、处理字段与属性名不匹配的方法也掌握了。多表查询、动态
113 0
|
2月前
|
JSON 前端开发 Java
第05课:Spring Boot中的MVC支持
第05课:Spring Boot中的MVC支持
168 0
|
8月前
|
SQL Java 数据库连接
对Spring、SpringMVC、MyBatis框架的介绍与解释
Spring 框架提供了全面的基础设施支持,Spring MVC 专注于 Web 层的开发,而 MyBatis 则是一个高效的持久层框架。这三个框架结合使用,可以显著提升 Java 企业级应用的开发效率和质量。通过理解它们的核心特性和使用方法,开发者可以更好地构建和维护复杂的应用程序。
372 29
|
9月前
|
设计模式 前端开发 Java
步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理
通过对 `DispatcherServlet`源码的深入剖析,我们了解了SpringMVC请求处理的全流程。`DispatcherServlet`作为前端控制器,负责请求的接收和分发,处理器映射和适配负责将请求分派到具体的处理器方法,视图解析器负责生成和渲染视图。理解这些核心组件及其交互原理,有助于开发者更好地使用和扩展SpringMVC框架。
206 4