当前位置: 首页 > news >正文

SpringMVC源码分析(九)--返回值解析器

1.返回值解析器介绍

返回值解析器用于解析Hanlder执行方法后的返回结果,例如将方法上标注有@ResponseBody注解的返回值解析成JSON、将方法返回的字符串作为视图名等

SpringMVC中默认的返回值解析器见RequestMappingHandlerAdapter#getDefaultReturnValueHandlers

private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(20);handlers.add(new ModelAndViewMethodReturnValueHandler());handlers.add(new ModelMethodProcessor());handlers.add(new ViewMethodReturnValueHandler());handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));handlers.add(new StreamingResponseBodyReturnValueHandler());handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),this.contentNegotiationManager, this.requestResponseBodyAdvice));handlers.add(new HttpHeadersReturnValueHandler());handlers.add(new CallableMethodReturnValueHandler());handlers.add(new DeferredResultMethodReturnValueHandler());handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));handlers.add(new ModelAttributeMethodProcessor(false));handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),this.contentNegotiationManager, this.requestResponseBodyAdvice));handlers.add(new ViewNameMethodReturnValueHandler());handlers.add(new MapMethodProcessor());// 添加自定义的返回值解析器if (getCustomReturnValueHandlers() != null) {handlers.addAll(getCustomReturnValueHandlers());}// 兜底的解析器if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));}else {handlers.add(new ModelAttributeMethodProcessor(true));}return handlers;
}

这些返回值解析器会被封装到HandlerMethodReturnValueHandlerComposite中,处理返回值时,会按照加入的顺序依次判断每个返回值解析器能否解析此任务,如果其中某个解析器能够解析此参数,则返回解析结果

2.自定义返回值解析器

在某些场景下,我们可以自定义返回值解析器,将响应的返回值转成我们希望的格式,假如我们想要将响应转换为yml格式,这时我们可以自定义注解,然后再自定义返回值解析器实现HandlerMethodReturnValueHandler接口,示例如下:

1)创建自定义注解@Yml及自定义返回值处理器YmlReturnResolver实现HandlerMethodReturnValueHandler接口

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Yml {
}public class YmlReturnResolver implements HandlerMethodReturnValueHandler {// 判断返回值解析器是否支持@Overridepublic boolean supportsReturnType(MethodParameter methodParameter) {Yml yml = methodParameter.getMethodAnnotation(Yml.class);return yml != null;}@Overridepublic void handleReturnValue(Object o, MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,NativeWebRequest nativeWebRequest) throws Exception {// 将返回值转换为yamlString str = new Yaml().dump(o);// 设置响应内容HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class);response.setContentType("text/plain;charset=utf-8");response.getWriter().print(str);// 设置请求已处理完毕modelAndViewContainer.setRequestHandled(true);}
}

2)配置类中加入自定义返回值解析器

@Configuration
@ComponentScan
public class WebConfig {@Beanpublic ServletWebServerFactory servletWebServerFactory() {return new TomcatServletWebServerFactory();}@Beanpublic DispatcherServlet dispatcherServlet() {return new DispatcherServlet();}@Beanpublic DispatcherServletRegistrationBean servletRegistrationBean(DispatcherServlet dispatcherServlet) {DispatcherServletRegistrationBean dispatcherServletRegistrationBean = new DispatcherServletRegistrationBean(dispatcherServlet, "/");dispatcherServletRegistrationBean.setLoadOnStartup(1);return dispatcherServletRegistrationBean;}@Beanpublic MyRequestMappingHandlerAdapter requestMappingHandlerAdapter() {MyRequestMappingHandlerAdapter handlerAdapter = new MyRequestMappingHandlerAdapter();// 添加自定义返回值解析器handlerAdapter.setCustomReturnValueHandlers(Arrays.asList(new YmlReturnResolver()));return handlerAdapter;}
}

3)创建控制器类及实体类

@Controller
public class Controller01 {@GetMapping("/test")@Ymlpublic User test() {

相关文章:

SpringMVC源码分析(九)--返回值解析器

1.返回值解析器介绍 返回值解析器用于解析Hanlder执行方法后的返回结果,例如将方法上标注有@ResponseBody注解的返回值解析成JSON、将方法返回的字符串作为视图名等 SpringMVC中默认的返回值解析器见RequestMappingHandlerAdapter#getDefaultReturnValueHandlers private L…...

京西商城——创建订单和获取订单接口

在之前的写过的接口中&#xff0c;我先后用了基于View和APIView来编写视图类 基于APIView类的时候相对于View会有很多便捷&#xff0c;但其实drf还在APIView的基础上又封装了一个 GenericAPIView 类&#xff0c;会大大减少了在编写视图时的重复代码和在修改代码时的工作量。 G…...

大话设计模式之模板方法模式

模板方法模式&#xff08;Template Method Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一个算法的框架&#xff0c;将特定步骤的实现延迟到子类中。模板方法模式通过在父类中定义算法的骨架&#xff0c;而将具体步骤的实现留给子类来完成&#xff0c;从而使子类…...

新model开发记录

模型使用 -- 用blender导出为 fbx &#xff0c;修改渲染方式&#xff08;点击模型->Materials->Extract Materials(将材质从fbx中 单独提取出来了)->Materials 选择 Shader -> SimpleURPToonLitExample 点开脸的材质&#xff0c;勾选第一条&#xff09; 解决角色…...

ARMday1

1.总结keil5下载代码和编译代码需要注意的事项 答&#xff1a;下载代码时&#xff0c;确保stlink的驱动有效、魔术棒中硬件型号的连接 编译代码时&#xff0c;先将配置魔术棒里Debug中的Setting&#xff0c;将Flash中Reset and Run勾选上&#xff0c;并去除pack中的Enab…...

【C++风云录】创造视觉奇迹:探索C++图形编程的魅力与可能性

图形与界面&#xff1a;从SFML到Allegro&#xff0c;探索C图形编程的世界 前言 随着计算机图形技术和界面设计的快速发展&#xff0c;图形编程在软件开发中变得越来越重要。C作为一种功能强大的编程语言&#xff0c;为开发人员提供了丰富的图形编程工具和库。本文将介绍几个流…...

常见的Nginx+Redis+MQ+DB架构设计

三高&#xff0c;复杂的架构 SQRS CAP 缓存&#xff0c;限流 【Redis&#xff0c;缓存】 cache-aside 缓存cache&#xff1a;数据源的副本 store 1. Read/Write Through Pattern 读写穿透模式 redis&#xff1a;放当前在线用户&#xff0c;热点数据...

vue+elementUI搭建动态表头的表格

前提&#xff1a;以下代码是vue2项目结合elementUi完成的 数据结构 后端传来的数据是两个list&#xff0c;一个表头的list&#xff0c;一个表格内容的list // 表头 headTableAtts: [{ columnLabel: 姓名, columnName: name },{ columnLabel: 年龄, columnName: age },{ colu…...

【ENSP】交换机和交换机之间实现静态路由

1.概念 三层交换机只能在Vlanif逻辑口配置iP地址 2.实现方法 交换机允许对应vlan通行&#xff0c;配置vlanif的ip地址&#xff0c;做静态路由 3.静态路由配置方法 ip route-static 目的网段 子网掩码 下一跳设备 LSW1三层交换机配置 u t m sys vlan batch 10 20 …...

2024.2.18力扣每日一题——N叉树的前序遍历

2024.2.18 题目来源我的题解方法一 深度优先遍历&#xff08;递归方式&#xff09;方法二 迭代方式&#xff08;栈实现&#xff09; 题目来源 力扣每日一题&#xff1b;题序&#xff1a;589 我的题解 方法一 深度优先遍历&#xff08;递归方式&#xff09; 与二叉树的前序遍…...

Taro活动列表中,对某一个活动添加分享按钮

采用data-留下分享链接的拼接参数 1.在item文件中写按钮 openType“share” <ButtonclassName{classes.rowRightShareButton}openType"share"data-share-transfer-id{lastGiftingTransferId}data-share-picture-url{shareUrl}data-share-title{shareTitle}onClic…...

深入理解计算机系统 家庭作业 2.65

/* 异或运算可以把同为1时变成0。 */ #include <stdio.h> #include <stdlib.h> int odd_ones(unsigned x); int main(void) { int x0xF00000016; printf("x的奇数位:%d",odd_ones(x)); return 0; } int odd_ones(unsigned x) { char…...

Java字节码

Java Agent概述 Java Agent是一种特殊类型的软件组件&#xff0c;它允许在Java虚拟机&#xff08;JVM&#xff09;运行时修改应用程序的字节码。这种技术通常用于性能监控、日志记录、系统调试等。Java Agent主要分为两类&#xff1a; 1. 启动时加载的Agent&#xff08;Pre-Ma…...

深入解析大数据体系中的ETL工作原理及常见组件

** 引言 关联阅读博客文章&#xff1a;探讨在大数据体系中API的通信机制与工作原理 关联阅读博客文章&#xff1a;深入理解HDFS工作原理&#xff1a;大数据存储和容错性机制解析 ** 在当今数字化时代&#xff0c;大数据处理已经成为了企业成功的重要组成部分。而在大数据处…...

条件变量的简易C++实现版

条件变量通常与互斥锁一起使用&#xff0c;用于线程间的同步。以下是条件变量常用的一些函数&#xff1a; ①std::condition_variable::wait(lock, pred)&#xff1a;线程调用此函数时&#xff0c;会原子性地释放锁并阻塞当前线程&#xff0c;等待另一个线程调用 notify_one 或…...

目标检测评价标准

主要借鉴&#xff1a;https://github.com/rafaelpadilla/Object-Detection-Metrics?tabreadme-ov-file 主要评价指标、术语&#xff1a; Intersection Over Union (IOU)&#xff1a;两个检测框交集面积与并集面积的比值 True Positive (TP)&#xff1a;IOU大于阈值的检测框…...

C51-- 蓝牙,WIFI模块

HC-08蓝牙模块: 蓝牙 -- 最好用的 串口透传 模块 透传 -- 透明传送&#xff0c;指的是在数据传输的过程中&#xff0c;通过无线的方式这组数据不发生任何形式的改变&#xff0c; 仿佛传输过程是透明的&#xff0c;同时保证传输质量&#xff0c;最终原封不动的传送到接收者手…...

HN热帖|替换Redis的一场赛跑

3 月 21 日&#xff0c; Redis Ltd. 宣布了一项重大决定&#xff1a;Redis “内存数据存储”项目从 Redis 7.4 版本开始将以非自由的、源代码可用的许可证发布。这一消息并不受欢迎&#xff0c;但也并非完全意外。这次的变化的不同寻常之处是市面上已经有了多个 Redis 替代品可…...

Kubernetes(k8s):网络插件之Calico安装与详解

Kubernetes&#xff08;k8s&#xff09;&#xff1a;网络插件之Calico安装与详解 1、什么是Calico&#xff1f;2、安装和配置Calico&#xff08;控制节点-master执行&#xff09;3、配置网络策略4、 Calico 的 yaml 文件部分详解1、ConfigMap配置2、DaemonSet 配置 5、calico-k…...

Chrome base 库详解:工具类和常用类库

Chrome浏览器使用了一个强大的库名为base&#xff0c;它包括了许多工具类和常用类库&#xff0c;以支持Chrome的底层功能和性能优化。在本文中&#xff0c;我们将详细阐述base库中的每个子项&#xff0c;并提供示例代码来展示其用法。 base 库的基本结构 Chrome的base库是一个…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...