消息转换器在SpringMVC执行流程

消息转换器的工作机制

内部工作流程
  1. 读取(Read)操作

    • 当接收到一个包含实体内容的HTTP请求时,Spring MVC会根据请求头中的Content-Type属性来确定应该使用哪个HttpMessageConverter来解析请求体。
    • DispatcherServlet会遍历已注册的HttpMessageConverter列表,寻找支持该Content-Type的转换器。
    • 一旦找到匹配的转换器,它将调用readInternal()方法,将输入流中的数据转换成Java对象,并将其作为控制器方法的参数传递。
  2. 写入(Write)操作

    • 在响应阶段,如果控制器方法返回了一个对象(例如通过@ResponseBodyResponseEntity),Spring MVC会根据客户端请求头中的Accept属性选择最合适的HttpMessageConverter
    • 它再次遍历HttpMessageConverter列表,这次是基于Accept头来决定哪个转换器最适合用于序列化返回的对象。
    • 找到匹配的转换器后,它会调用writeInternal()方法,将Java对象转换为输出流格式的数据,并设置响应的内容类型。
  3. 优先级规则

    • 如果有多个HttpMessageConverter都能处理相同的媒体类型,Spring MVC会根据它们的优先级来选择最合适的一个。优先级通常由实现类自身定义,也可以通过配置调整。
  4. 支持的内容类型

    • 每个HttpMessageConverter都声明了它能够处理的一组媒体类型(MIME types)。例如,MappingJackson2HttpMessageConverter通常支持application/json,而Jaxb2RootElementHttpMessageConverter则可能支持application/xml等。
    • 这意味着只有当请求或响应的Content-TypeAccept头与某个转换器支持的媒体类型相匹配时,该转换器才会被选中进行实际的数据转换工作。
数据绑定与校验
  • 数据绑定:Spring MVC框架可以自动地将HTTP请求中的查询参数、路径变量以及表单字段绑定到控制器方法的参数上。对于复杂的对象结构,如JSON或XML格式的数据,则需要HttpMessageConverter来进行反序列化。

  • 校验:如果控制器方法参数上有@Valid@Validated注解,Spring会调用校验框架(如Hibernate Validator)对传入的对象进行验证。如果校验失败,可以抛出异常或者返回错误信息给客户端。

配置HttpMessageConverter

开发者可以通过多种方式配置HttpMessageConverter

  • 全局配置:在Spring Boot应用中,可以在application.propertiesapplication.yml文件中指定默认的HttpMessageConverter设置。例如,你可以调整Jackson库的行为以改变JSON序列化/反序列化的规则。

  • 编程式配置:通过创建一个实现了WebMvcConfigurer接口的配置类,并重写extendMessageConverters方法,你可以添加、移除或自定义HttpMessageConverter实例。

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {// 添加或修改现有的HttpMessageConverterconverters.add(new CustomHttpMessageConverter());}
}
  • 自定义转换器:如果你的应用需要处理非标准的数据格式,你可以编写自己的HttpMessageConverter实现,并将其添加到Spring MVC的转换器列表中。

请求处理流程中的具体运作

以下是更为详细的请求处理流程:

  1. 接收HTTP请求:Web服务器接收到HTTP请求并转发给DispatcherServlet

  2. HandlerMapping选择处理器DispatcherServlet根据URL模式或其他条件查找适当的控制器方法。

  3. 拦截器链预处理:如果有配置拦截器,它们会在请求到达目标处理器之前进行预处理。

  4. 准备调用控制器方法

    • 解析请求参数DispatcherServlet检查是否有任何@RequestBody标注的方法参数。如果是,它会遍历已注册的HttpMessageConverter,寻找能处理当前Content-Type的转换器,并使用它来解析请求体为Java对象。

    • 数据验证:如果存在@Valid@Validated注解,Spring会调用校验框架对传入的对象进行校验。

  5. 调用控制器方法:所有准备工作完成后,DispatcherServlet调用相应的控制器方法。

  6. 处理方法返回值

    • 视图解析:如果控制器方法返回的是视图名称或ModelAndViewViewResolver会负责渲染视图。

    • 响应体转换:对于标记了@ResponseBody的方法,或者是返回了ResponseEntityHttpEntity类型的对象,Spring会再次遍历HttpMessageConverter列表,根据Accept头选择适合的转换器,将返回的对象序列化为HTTP响应体。

  7. 拦截器链后处理:如果有配置拦截器,它们可以在控制器方法执行后进行后处理。

  8. 发送响应DispatcherServlet构建完整的HTTP响应,并发送回客户端。

  9. 结束请求:整个请求-响应周期完成,资源释放,等待下一个请求到来。

HttpMessageConverter示例

接下来,我们将详细展示如何创建和配置一个自定义的消息转换器,用于处理特定的文本格式(假设是CSV格式)。

自定义HttpMessageConverter实现

首先,我们需要创建一个新的类继承自AbstractHttpMessageConverter<T>,其中T是我们想要转换的目标类型。在这个例子中,我们将处理List<String>类型的CSV数据。

import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;public class CsvHttpMessageConverter extends AbstractHttpMessageConverter<List<String>> {public CsvHttpMessageConverter() {super(MediaType.parseMediaType("text/csv"));}@Overrideprotected boolean supports(Class<?> clazz) {return List.class.isAssignableFrom(clazz);}@Overrideprotected List<String> readInternal(Class<? extends List<String>> clazz, HttpInputMessage inputMessage)throws IOException, HttpMessageNotReadableException {try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputMessage.getBody(), "UTF-8"))) {String line;List<String> result = new ArrayList<>();while ((line = reader.readLine()) != null) {result.addAll(List.of(line.split(",")));}return result;}}@Overrideprotected void writeInternal(List<String> t, HttpOutputMessage outputMessage)throws IOException, HttpMessageNotWritableException {try (OutputStreamWriter writer = new OutputStreamWriter(outputMessage.getBody(), "UTF-8")) {for (int i = 0; i < t.size(); i++) {writer.write(t.get(i));if (i < t.size() - 1) {writer.write(",");}}}}
}
注册自定义HttpMessageConverter

然后,我们需要在Spring配置中注册这个自定义的消息转换器。这可以通过实现WebMvcConfigurer接口并在其extendMessageConverters方法中添加我们的转换器来完成。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.List;@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(new CsvHttpMessageConverter());}
}
使用自定义HttpMessageConverter

最后,我们可以在控制器中使用这个自定义的消息转换器来处理CSV格式的数据。例如:

@RestController
@RequestMapping("/csv")
public class CsvController {@PostMapping(consumes = "text/csv", produces = "text/csv")public ResponseEntity<List<String>> handleCsv(@RequestBody List<String> csvData) {// 处理CSV数据...return ResponseEntity.ok(csvData);}
}

在这个例子中,我们创建了一个名为CsvHttpMessageConverter的类,它可以处理text/csv类型的数据。然后我们在配置类中将这个自定义的转换器添加到了Spring MVC的HttpMessageConverter列表中。通过这种方式,你可以根据应用程序的具体需求定制化消息转换过程,确保你的API能够正确地解析和生成各种格式的数据。

总结

综上所述,HttpMessageConverter在Spring MVC中扮演着至关重要的角色,它使得开发者可以专注于业务逻辑,而无需关心如何从HTTP请求中解析数据或如何构建HTTP响应。通过深入了解其工作机制、配置方法以及如何扩展和自定义转换器,我们可以更好地利用Spring MVC的强大功能来构建高效、灵活的Web应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/66209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件逆向之标志位

进位标志CF&#xff08;Carry Flag&#xff09; 介绍&#xff1a;如果运算结果的最高位产生了一个进位&#xff08;加法&#xff09;或借位&#xff08;减法&#xff09;&#xff0c;那么&#xff0c;其值为1&#xff0c;否则其值为0。无符号数。 示例&#xff1a; mov al&…

【mybatis-plus问题集锦系列】mybatis使用xml配置文件实现数据的基础增删改查

简单的数据查询&#xff0c;我们可以在mapper接口里面去实现&#xff0c;但是如果是复杂的查询&#xff0c;我们就可以使用xml配置文件去做&#xff0c; 官网链接xml配置文件 实现效果 实现代码 根据mapper接口的包结构&#xff0c;在resources包里面新建同名同结构的xml文件…

(leetcode算法题)384. 打乱数组 398. 随机数索引

问题转化&#xff1a; 题目要求将nums中的数字出现的次序随机打乱 转化成&#xff1a;对于 0 号位置来说&#xff0c;nums[i], ..., nums[n - 1] 可以等概率的出现 ... && ... && 对于 n - 1号位置来说&#xff0c;nums[i], ..., nums[n - 1] 可以等概率的出…

FPGA交通灯实现

1 原理 FPGA(现场可编程门阵列)交通灯实现原理主要是基于硬件描述语言(如VHDL或Verilog)编程,通过FPGA内部的逻辑单元和寄存器来实现交通灯的控制功能。以下是对FPGA交通灯实现原理的详细解释: 一、交通灯的基本功能 交通灯的主要功能包括红灯、黄灯和绿灯的显示,以及…

现代光学基础4

总结自老师的讲义 yt4 分子中的光学过程 - 开卷考试复习资料 目录 能级结构与跃迁类型 能级结构跃迁类型 光学吸收 电子吸收红外吸收 荧光、磷光与光漂白 荧光磷光光漂白 拉曼散射 发现与特性基本机制与红外光谱的比较和选择定则 1. 能级结构与跃迁类型 能级结构 电子态与…

【AimRT】AimRT Hello World

目录 一、工程结构二、源码说明/CMakeLists.txt/cmake/GetAimRT.cmake/src/CMakeLists.txt/src/module/helloworld_module/CMakeLists.txt/src/app/helloworld_app/CMakeLists.txt/src/install/cfg/helloworld_cfg.yaml/src/module/helloworld_module/helloworld_module.h/src/…

uniapp H5 对接 声网,截图

文章目录 安装依赖创建容器容器样式 javascript代码ImageDataToBlob 方法 控制控制台LOG输出 安装依赖 版本"agora-rtc-sdk-ng": "^4.22.0", 创建容器 <template><view class"videoValue " id"videoValue"><u-toast…

Global 远程需求

需求 1 周期&#xff1a;半年 rate&#xff1a;税后 30-40k/月&#xff0c;free 模式 公司&#xff1a;外资咨询 项目地点&#xff1a;远程为主 语言要求&#xff1a;英语 具体JD Task Description&#xff1a; •Refinement of user stories (together with Product Own…

Pycharm连接远程解释器

这里写目录标题 0 前言1 给项目添加解释器2 通过SSH连接3 找到远程服务器的torch环境所对应的python路径&#xff0c;并设置同步映射&#xff08;1&#xff09;配置服务器的系统环境&#xff08;2&#xff09;配置服务器的conda环境 4 进入到程序入口&#xff08;main.py&#…

kafka使用以及基于zookeeper集群搭建集群环境

一、环境介绍 zookeeper下载地址&#xff1a;https://zookeeper.apache.org/releases.html kafka下载地址&#xff1a;https://kafka.apache.org/downloads 192.168.142.129 apache-zookeeper-3.8.4-bin.tar.gz kafka_2.13-3.6.0.tgz 192.168.142.130 apache-zookee…

rsync命令常用同步方案

rsync是一个高效的文件同步工具&#xff0c;广泛应用于本地和远程备份、镜像及同步任务。它通过增量同步、压缩传输以及远程协议&#xff08;如SSH&#xff09;等技术&#xff0c;显著提高了文件传输的效率。本文将介绍rsync命令的常用参数、工作原理、常见同步方案&#xff0c…

JavaScript学习-入门篇

​ JavaScript的运行环境 开发环境就是开发JavaScript代码所需的环境&#xff0c;一般建议新手刚刚开始使用一些记事本工具&#xff08;如sublime、editPlus、VScode&#xff09;&#xff0c;锻炼代码的手感。等学习到一定阶段&#xff0c;就可以使用集成开发工具IDE&#xff0…

SQL把字符串按逗号分割成记录

在 SQL 中&#xff0c;可以通过以下方法将字符串按逗号分割&#xff0c;并将每个分割的值作为单独的记录插入到结果集中。以下是针对不同数据库系统的实现方法&#xff1a; 1. 使用 STRING_SPLIT&#xff08;SQL Server 2016&#xff09; STRING_SPLIT 是 SQL Server 提供的内置…

大模型系列18-AI Agents

什么是AI Agents Al Agent智能体&#xff0c;是指一种能够模拟人类思考和行为来自动执行任务&#xff0c;以解决复杂问题的程序或系统 架构图 思考->行动->观测 思考依赖记忆以及规划决策&#xff0c;行动依赖工具&#xff0c;观测依赖感知 举例 长沙今天白天和晚上的…

mysql自定义安装

1、下载安装包 我是在windows上安装&#xff0c;所以选择“Mysql Installer for Windows” 2、安装mysql 双击“mysql-installer-community-8.0.40.0.msi”&#xff0c;开始启动安装 这里选择安装项&#xff0c;这里只选择了两项。workbench是图形化管理工具&#xff0c;比较吃…

22408操作系统期末速成/复习(考研0基础上手)

第一部分:计算题&#xff1a; 考察范围&#xff1a;&#xff08;标红的是重点考&#xff09; 第一章&#xff1a;CPU利用率&#xff1a; 第二章&#xff1a; 进程调度算法&#xff08;需要注意不同调度算法的优先级和题目中给出的是否可以抢占【分为可抢占和不可抢占&#xff…

数据去重与重复数据的高效处理策略

在实际业务中&#xff0c;数据去重是一个非常常见的需求&#xff0c;特别是在日志数据、用户操作记录或交易记录等领域。去重不仅仅是删除重复数据&#xff0c;更重要的是按照业务规则保留最有价值的数据记录。 本文将探讨如何在 SQL 中高效地处理重复数据&#xff0c;通过 DI…

综合能源建模:理论、方法与实践

一、引言 随着全球能源需求的持续增长以及对能源安全、环境保护和可持续性发展的日益关注&#xff0c;综合能源系统&#xff08;Integrated Energy System&#xff0c;IES&#xff09;作为一种能够整合多种能源资源、实现能源高效利用和协同优化的解决方案&#xff0c;正逐渐成…

【Leetcode 热题 100】74. 搜索二维矩阵

问题背景 给你一个满足下述两条属性的 m n m \times n mn 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 t a r g e t target target&#xff0c;如果 t a r g e t target target 在矩阵中&…

DOS攻击的原理和实现 (网络安全)hping3和Slowloris的运用

DoS攻击的原理和实现 DoS攻击&#xff08;Denial of Service Attack&#xff0c;拒绝服务攻击&#xff09;是指通过恶意手段使目标服务器、服务或网络资源无法正常提供服务&#xff0c;从而影响正常用户的访问。DoS攻击通常通过消耗目标系统的资源&#xff08;如带宽、内存、处…