SpringBoot2.x系列教程18--ContentNegotiatingViewResolver实现同一接口输出不同的View内容

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 前言在上一章节中,壹哥 给大家讲解了ContentNegotiating内容协商的简单使用及原理分析,让我们明白了内容协商在HttpMessage上的作用。我们知道,利用ContentNegotiating可以实现访问同一个URL接口,可以访问不同格式的数据,比如返回JSON、XML格式;那么如果我想使用同样的数据内容来呈现出不同的View该怎么办呢?这就要用到我今天要讲的内容了。内容协商不仅可以作用在HttpMessage上面,还可以作用在我们输出的View视图内容上,本章节我会继续讲解这一块的内容。一. 内容协商视图解析器1. 概述我们利用ContentNegotiatin

前言

在上一章节中,壹哥 给大家讲解了ContentNegotiating内容协商的简单使用及原理分析,让我们明白了内容协商在HttpMessage上的作用。

我们知道,利用ContentNegotiating可以实现访问同一个URL接口,可以访问不同格式的数据,比如返回JSON、XML格式;那么如果我想使用同样的数据内容来呈现出不同的View该怎么办呢?这就要用到我今天要讲的内容了。

内容协商不仅可以作用在HttpMessage上面,还可以作用在我们输出的View视图内容上,本章节我会继续讲解这一块的内容。

一. 内容协商视图解析器

1. 概述

我们利用ContentNegotiatingViewResolver内容协调视图解析器,可以实现RESTful中的一个重要特性,即对同一个URL资源,可以有多种表述方式。ContentNegotiatingViewResolver视图解析器可以允许我们使用同样的内容数据来呈现出不同的View。

但ContentNegotiatingViewResolver自己并不解析视图,而是委派给其他的视图处理器。为了使这个解析器正常工作,order序号需要设置成比其他的视图处理器高的优先级(默认就是最高的)。

2. ContentNegotiatingViewResolver细节:

  • ContentNegotiationManager用于内容协商的策略可以手动设置指定,也可以通过FactoryBean自动生成;
  • viewResolvers默认是去容器内找到所有的,当然你也可以手动set进来;
  • 使用request的媒体类型,根据扩展名选择不同的view输出不同的格式;
  • 不是自己处理view,而是代理给不同的ViewResolver来处理不同的view;
  • 默认是支持Accept和后缀的协商方式的。并且还支持 逻辑视图名.后缀的视图解析方式;
  • 依据View.getContentType匹配MediaType来完成的最佳匹配。

3. 内容协调视图解析器工作原理图

二. ContentNegotiatingViewResolver的使用

在默认情况下,SpringMVC并没有开启ContentNegotiatingViewResolver内容协商视图解析器,因此如果有同一接口资源,要用多视图展示的需求,我们是需要自己手动配置来实现的。

所以接下来我会带大家,实现访问同一个URL接口,返回多个View的效果。

1. 需求介绍

我们要对同一个RESTful风格的URL,根据请求的不同,可以得到一个PDF视图,一个JSON视图,一个Html视图。

2. 创建web项目(略)

参照之前的案例,我们创建一个新的web项目,过程略去。

3. 创建View视图

我们在项目中创建一个com.yyg.boot.resolver包,在这个包中创建如下3个核心代码类。

3.1 创建PdfViewResolver类

创建一个可以输出PDF内容的视图解析类。

packagecom.yyg.boot.resolver;
importorg.springframework.http.MediaType;
importorg.springframework.web.servlet.View;
importorg.springframework.web.servlet.ViewResolver;
importorg.springframework.web.servlet.view.ContentNegotiatingViewResolver;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.util.Map;
/*** @Description Description* @Author 一一哥Sun* @Date Created in 2020/3/22*/publicclassPdfViewResolverimplementsView {
@OverridepublicStringgetContentType() {
returnMediaType.APPLICATION_PDF_VALUE;
    }
@Overridepublicvoidrender(Map<String, ?>model, HttpServletRequestrequest, HttpServletResponseresponse) throwsException {
response.getWriter()
            .write("<html><body style='color:red'>This is [PDF] view</body></html>");
    }
}

3.2 创建ExcelViewResolver类

创建一个可以输出Excel内容的视图解析类。

packagecom.yyg.boot.resolver;
importorg.springframework.http.MediaType;
importorg.springframework.web.servlet.View;
importorg.springframework.web.servlet.view.ContentNegotiatingViewResolver;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.util.Map;
/*** @Description Description* @Author 一一哥Sun* @Date Created in 2020/3/22*/publicclassExcelViewResolverimplementsView {
@OverridepublicStringgetContentType() {
returnMediaType.APPLICATION_JSON_UTF8_VALUE;
    }
@Overridepublicvoidrender(Map<String, ?>model, HttpServletRequestrequest, HttpServletResponseresponse) throwsException {
response.getWriter()
                .write("<html><body style='color:blue'>This is [JSON] view!</body></html>");
    }
}

3.3 创建HtmlViewResolver类

创建一个可以输出HTML内容的视图解析类。

packagecom.yyg.boot.resolver;
importorg.springframework.http.MediaType;
importorg.springframework.web.servlet.View;
importorg.springframework.web.servlet.view.ContentNegotiatingViewResolver;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.util.Map;
/*** @Description Description* @Author 一一哥Sun* @Date Created in 2020/3/22*/publicclassHtmlViewResolverimplementsView {
@OverridepublicStringgetContentType() {
returnMediaType.TEXT_HTML_VALUE;
    }
@Overridepublicvoidrender(Map<String, ?>model, HttpServletRequestrequest, HttpServletResponseresponse) throwsException {
response.getWriter()
                .write("<html><body style='color:green'>This is [HTML] view!</body></html>");
    }
}

3.4 最终目录结构图

下图是以上3个类的最终存储位置。

4. 进行视图配置

将上面创建的视图注册到内容协调视图解析器中,开启Spring MVC在视图上对ContentNegotiation内容协商的支持。

packagecom.yyg.boot.config;
importcom.yyg.boot.resolver.ExcelViewResolver;
importcom.yyg.boot.resolver.HtmlViewResolver;
importcom.yyg.boot.resolver.PdfViewResolver;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.http.MediaType;
importorg.springframework.web.servlet.View;
importorg.springframework.web.servlet.ViewResolver;
importorg.springframework.web.servlet.config.annotation.ViewResolverRegistry;
importorg.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
importorg.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
importorg.springframework.web.servlet.view.ContentNegotiatingViewResolver;
importorg.springframework.web.servlet.view.InternalResourceViewResolver;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjava.util.Locale;
importjava.util.Map;
/*** @Description Description* @Author 一一哥Sun* @Date Created in 2020/3/22*/@ConfigurationpublicclassWebMvcConfigextendsWebMvcConfigurationSupport {
@OverridepublicvoidconfigureViewResolvers(ViewResolverRegistryregistry) {
registry.enableContentNegotiation(newPdfViewResolver());
registry.enableContentNegotiation(newExcelViewResolver());
registry.enableContentNegotiation(newHtmlViewResolver());
// 上面三个注册方法必须在此方法之上执行registry.enableContentNegotiation(false);
    }
}

5. 创建Controller测试接口

然后我们创建一个Controller接口,方便后面进行调用测试。

packagecom.yyg.boot.web;
importlombok.extern.slf4j.Slf4j;
importorg.springframework.http.MediaType;
importorg.springframework.stereotype.Controller;
importorg.springframework.util.MimeType;
importorg.springframework.web.bind.annotation.GetMapping;
importorg.springframework.web.bind.annotation.PathVariable;
importorg.springframework.web.bind.annotation.ResponseBody;
/*** @Description 内容协商视图解析器* @Author 一一哥Sun* @Date Created in 2020/3/21*/@Slf4j@ControllerpublicclassNegotiationController {
@GetMapping(value="/show/{type}")
publicStringshowUser(@PathVariable("type") Stringtype) {
log.warn("type={}", type);
return"跟一一哥学习ContentNegotiatingViewResolver!";
    }
}

6. 启动程序运行测试

6.1 测试输出pdf内容视图

重启项目后,我们在浏览器中输入地址:
http://localhost:8080/show/a.pdf

可以看到如下效果:

6.2 测试输出json内容视图

如果我们在浏览器中输入如下地址:
http://localhost:8080/show/a.json

可以看到如下效果:

6.3 测试输出html内容视图

如果我们在浏览器中输入如下地址:
http://localhost:8080/show/a.html

可以看到如下效果:

6.4 测试默认视图

而在没有后缀名的情况下,以Accept的规则为准。

所以可见扩展名的规则优先级高于Accept,符合我们上一章节中的理论知识。若没有指定请求的扩展名,则Accept就会生效!

结语

至此,我们就利用ContentNegotiatingViewResolver实现了今天的效果,虽然ContentNegotiatingViewResolver这个类名看着很长,但是实际使用起来也并不是很难,你学会了吗?

今日小作业:

请在学生管理系统中,设计一个学生自我介绍功能,能够以不同的格式输出学生信息。

目录
打赏
0
1
1
0
16
分享
相关文章
|
18天前
|
SpringBoot:SpringBoot通过注解监测Controller接口
本文详细介绍了如何通过Spring Boot注解监测Controller接口,包括自定义注解、AOP切面的创建和使用以及具体的示例代码。通过这种方式,可以方便地在Controller方法执行前后添加日志记录、性能监控和异常处理逻辑,而无需修改方法本身的代码。这种方法不仅提高了代码的可维护性,还增强了系统的监控能力。希望本文能帮助您更好地理解和应用Spring Boot中的注解监测技术。
53 16
精通SpringBoot:16个扩展接口精讲
【10月更文挑战第16天】 SpringBoot以其简化的配置和强大的扩展性,成为了Java开发者的首选框架之一。SpringBoot提供了一系列的扩展接口,使得开发者能够灵活地定制和扩展应用的行为。掌握这些扩展接口,能够帮助我们写出更加优雅和高效的代码。本文将详细介绍16个SpringBoot的扩展接口,并探讨它们在实际开发中的应用。
78 1
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
本文为Spring Boot增删改查接口的小白入门教程,介绍了项目的构建、配置YML文件、代码编写(包括实体类、Mapper接口、Mapper.xml、Service和Controller)以及使用Postman进行接口测试的方法。同时提供了SQL代码和完整代码的下载链接。
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
掌握SpringBoot扩展接口:提升代码优雅度的16个技巧
【10月更文挑战第20天】 SpringBoot以其简化配置和快速开发而受到开发者的青睐。除了基本的CRUD操作外,SpringBoot还提供了丰富的扩展接口,让我们能够更灵活地定制和扩展应用。以下是16个常用的SpringBoot扩展接口,掌握它们将帮助你写出更加优雅的代码。
164 0
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
本文详细介绍了如何在SpringBoot项目中统一处理接口返回结果及全局异常。首先,通过封装`ResponseResult`类,实现了接口返回结果的规范化,包括状态码、状态信息、返回信息和数据等字段,提供了多种成功和失败的返回方法。其次,利用`@RestControllerAdvice`和`@ExceptionHandler`注解配置全局异常处理,捕获并友好地处理各种异常信息。
2911 0
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
springboot文件上传和下载接口的简单思路
本文介绍了在Spring Boot中实现文件上传和下载接口的简单思路。文件上传通过`MultipartFile`对象获取前端传递的文件并存储,返回对外访问路径;文件下载通过文件的uuid名称读取文件,并通过流的方式输出,实现文件下载功能。
springboot文件上传和下载接口的简单思路
Spring Boot 3 实现GZIP压缩优化:显著减少接口流量消耗!
在Web开发过程中,随着应用规模的扩大和用户量的增长,接口流量的消耗成为了一个不容忽视的问题。为了提升应用的性能和用户体验,减少带宽占用,数据压缩成为了一个重要的优化手段。在Spring Boot 3中,通过集成GZIP压缩技术,我们可以显著减少接口流量的消耗,从而优化应用的性能。本文将详细介绍如何在Spring Boot 3中实现GZIP压缩优化。
619 6
微信小程序+SpringBoot接入后台服务,接口数据来自后端
这篇文章介绍了如何将微信小程序与SpringBoot后端服务进行数据交互,包括后端接口的编写、小程序获取接口数据的方法,以及数据在小程序中的展示。同时,还涉及到了使用Vue搭建后台管理系统,方便数据的查看和管理。
微信小程序+SpringBoot接入后台服务,接口数据来自后端
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等