Spring MVC学习 | 报文信息转换

news2025/1/20 1:08:56

文章目录

  • 一、HttpMessageConverter
  • 二、获取请求报文信息
    • 2.1 使用原生servletAPI
    • 2.2 使用@RequestBody注解获取请求体信息
    • 2.3 使用RequestEntity对象获取请求报文信息
  • 三、设置响应报文信息
    • 3.1 使用原生的servletAPI
    • 3.2 使用@ResponseBody注解设置响应体信息
    • 3.3 ResponseEntity类的使用
    • 3.4 关于响应体信息的中文乱码问题
  • 四、Spring MVC处理Json和Ajax数据
    • 4.1 处理Json数据
    • 4.2 处理Ajax数据


学习视频🎥:https://www.bilibili.com/video/BV1Ry4y1574R

一、HttpMessageConverter

💬概述HttpMessageConverter是Spring MVC中的一个类,意思是报文信息转换器
🔑作用:可以将报文信息和Java对象进行转换,即请求报文信息转换成Java对象,Java对象转换成响应报文信息
🔑HttpMessageConverter提供了两个注解和两个类型,用于实现报文信息与Java对象的转化

  1. @RequestBody:获取请求体信息的注解,作用于控制器方法形参,此时形参中就封装了请求体信息
  2. @ResponseBody:设置响应体信息的注解,作用于控制器方法,此时控制器方法的返回值就作为响应体的信息
  3. RequestEntity:获取请求报文的类,作为控制器方法的形参类型上,此时该形参对象就封装了请求报文的全部信息,包括请求头和请求体
  4. ResponseEntity:设置响应报文的类,作为控制器方法的返回值类型,此时可以在控制器方法内创建一个ResponseEntity对象,通过该对象可以设置响应报文的信息(自定义响应报文),最后返回该对象

二、获取请求报文信息

❓ 解决中文乱码问题:获取请求报文信息时,可能会出现中文乱码问题,尤其是获取请求参数,解决办法就是在web.xml中配置Spring MVC内部的字符编码过滤器CharacterEncodingFilter,然后设置encoding属性值为utf-8即可

2.1 使用原生servletAPI

🔑使用方式:在控制器方法中添加HttpServletRequest类型的形参req,通过req请求对象调用相关方法获取请求报文信息

@RequestMapping("/testReqMsg01")
public String showTestReqMsg01(HttpServletRequest req) throws IOException {
    // 获取请求头信息
    System.out.println("请求头Host的信息 --> " + req.getHeader("Host"));
    return "success";
}

2.2 使用@RequestBody注解获取请求体信息

🔑使用方式:在控制器方法中添加String类型的形参reqBody,然后在形参前添加@RequestBody注解,此时请求体信息就以字符串形式封装在reqBody,打印reqBody就能看到对应的请求体信息

@RequestMapping("/testReqMsg02")
public String showTestReqMsg02(@RequestBody String reqBody) {
    System.out.println("请求体信息 -->" + reqBody);

    return "success";
}

2.3 使用RequestEntity对象获取请求报文信息

🔑使用方式:在控制器方法中添加RequestEntity<String>类型的形参reqEntity,此时reqEntity对象中就封装了请求报文中的全部信息,reqEntity同样可以调用相关方法获取请求头信息和请求体信息

@RequestMapping("/testReqMsg03")
public String showTestReqMsg03(RequestEntity<String> reqEntity) {
    // 获取请求头信息
    System.out.println("全部请求头信息 -->" + reqEntity.getHeaders());

    // 获取请求体信息
    System.out.println("请求体信息 --> " + reqEntity.getBody());
    return "success";
}

🔑RequestEntity对象 🆚 HttpServletRequest对象

  • 请求头信息的获取
    RequestEntity对象能获取直接获取请求头的全部信息,并以字符串形式打印 --> getHeaders()
    HttpServletRequest对象只能通过请求头的某个键来获取对应的值 --> getHeader("键名")getHeaders("键名")
  • 请求体信息的获取
    RequestEntity对象能直接获取请求体的信息(即全部请求参数),并以字符串形式打印 --> getBody()
    HttpServletRequest对象只能通过IO流来获取请求体中的请求参数 --> getReader()getInputStream()

三、设置响应报文信息

3.1 使用原生的servletAPI

🔑使用方法:创建控制器方法,因为设置响应体信息只需将信息打印到当前页面(是指控制器方法中@RequestMapping注解所设置的请求路径)即可,无需跳转页面,所以方法不需要返回值,直接返回类型设置为void,然后在方法中添加HttpServletResponse类型的形参resp,通过resp调用相关方法设置响应报文信息

@RequestMapping("/testRespMsg01")
public void showTestRespMsg01(HttpServletResponse resp) throws IOException {
    // 设置响应体的编码方式
    resp.setContentType("text/html;charset=utf-8");

    // 设置响应体信息,将信息打印到页面
    resp.getWriter().print("测试原生servletAPI设置响应报文信息成功!");
}

3.2 使用@ResponseBody注解设置响应体信息

🔑使用方式:在控制器方法上添加@ResponseBody注解,此时控制器方法的返回值不再是视图名称,而是作为响应体信息,即打印到页面上的信息

@RequestMapping("/testRespMsg02")
@ResponseBody
public String showTestRespMsg02() {
    return "测试@ResponseBody注解成功!";
}

🔑复合注解——@RestController(以后常用)

  • 概述:因为在以后的开发中,@ResponseBody注解会经常使用,因此Spring MVC提供了一个复合注解@RestController,该复合注解是@Controller注解和@ResponseBody注解的组合,也结合了两个注解的作用
  • 标识的位置:@RestController注解作用于控制器上(此时不用添加@Controller注解)
  • 作用
    ① 将类标识为控制器类 --> @Controller的作用
    ② 在对应控制器的所有控制器方法上自动添加上@ResponseBody注解,不用我们手动添加 --> @ResponseBody的作用

3.3 ResponseEntity类的使用

💬概述ResponseEntity对象就是响应报文对象,它作用于控制器方法返回值类型,需要加上泛型<T>,在控制器方法中创建一个ResponseEntity对象respEntity,通过该对象能自定义响应报文信息,设置完信息后就将对象返回,此时控制器方法返回值就是响应到浏览器的响应报文

🔑使用ResponseEntity对象多用于文件下载功能的实现,因为文件下载中需要设置响应头以及响应体的MIME类型,而ResponseEntity对象正好可以实现,文件下载的具体实现下面介绍

🔑ResponseEntity对象的创建ResponseEntity类中有多个构造器,这里介绍构造器中需要传入的几个重要参数

构造器的参数参数类型解释
bodyT响应体对象,可以为null,对应响应体信息;T表示泛型,即创建ResponseEntity时指定的泛型
headersMultiValueMap<String, String>请求头对象,可以为null,对应响应头信息;用于设置响应头信息;MultiValueMap是继承Map的接口,因此创建Headers对象时需要使用MultiValueMap接口的实现类——HttpHeaders
statusHttpStatus响应状态码对象,对应响应状态码;可以直接通过HttpStatus.状态来获取对应的状态码,如HttpStatus.OK(200)

💡 文件下载功能中泛型T设置为byte[]类型,即字节数组类型,用于存储文件对应的全部字节,此时文件对应的字节数组就是响应体信息
💡 ResponseEntity在文件下载中的使用:SpringMVC实现文件上传和下载#文件下载⬇

3.4 关于响应体信息的中文乱码问题

🔑解决办法

  • 对于HttpServletResponse对象:使用原生的servletAPIHttpServletResponse设置响应体信息时,需要在设置响应体信息前设置响应体信息编码方式,使用setContentType("text/html;charset-utf-8")方法,告知浏览器响应体的MIME类型以及编码方式,才能避免出现中文乱码问题(即使在web.xml中配置的CharacterEncodingFilter过滤器已经设置过forceResponseEncoding属性,也要添加setContentType()方法(具体原因🚩)

  • 对于@ResponseBody注解:使用@ResponseBody注解时也会遇到中文乱码问题,有多种解决方式,这里介绍两种

    ① 在springmvc.xml的开启注解驱动<mvc:annoattion-driven>标签修改报文信息转换器默认的编码方式

    <mvc:annotation-driven >
        <!-- 报文信息转换器 -->
        <mvc:message-converters register-defaults="true">
            <!-- 修改字符集编码方式,解决@RequestBody出现中文乱码问题 -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    

    ② 对于@ResponseBody所标识的控制器方法,在控制器方法的@RequestMapping注解中添加一个produces属性,属性值设置为"text/html;charset=UTF-8"即可(适合完全注解开发)

    @RequestMapping(
        value = "/testRespMsg02",
        produces = "text/html;charset=utf-8"
    )
    @ResponseBody
    public String showTestRespMsg02() {
        return "测试@ResponseBody注解成功!";
    }
    
  • 设置响应时的编码方式的两种方式
    resp.setCharacterEncoding("UTF-8"):仅设置了服务器中servlet对响应体进行编码时采用的编码方式,没有对浏览器解码时的解码方式做要求。但不同浏览器对响应信息的解码方式一般不同,与服务器编码时的编码方式也不一定会相同,所以用这种方式设置响应时编码方式可能会失效。🚩而字符编码过滤器CharsetEncodingFilter中设置响应时编码方式采用的正是这种方式,所以配置过滤器时设置的forceResponseEncoding属性也可能会失效
    resp.setContentType("MIME类型;charset=UTF-8"):该方式一举三得,Ⅰ)设置响应体的MIME类型;Ⅱ)设置响应体在服务器端编码时的编码方式;Ⅲ)告知浏览器响应体的编码方式并让浏览器采用相同的解码方式对响应体信息进行解码。因此就能避免打印到页面的响应体信息出现中文乱码,一般都直接采用这种方式设置响应时编码方式,不采用上面的方式

  • 不同格式的中文乱码

    ① 中文字符部分类似于'烇湫'的格式,而且有可能隔壁的英文字母也会被乱码吃掉,说明服务器端对响应体的编码方式与浏览器的解码方式不一样,一般是因为没有设置响应时编码方式或者仅添加了resp.setCharacterEncoding("UTF-8")respMsg-coding01

    ② 中文字符都是问号'??',说明服务器端的编码方式与浏览器的解码方式一样,但采用的编解码方式不能识别中文字符,比如采用了默认的iso8859-1,一般是因为没有设置响应时的编码方式所造成的respMsg-coding02


四、Spring MVC处理Json和Ajax数据

4.1 处理Json数据

① 导入相关jar包:添加jackson-databind.jar包

② 开启注解驱动:在springmvc.xml核心配置文件中开启注解驱动,此时在HandlerAdaptor中会自动装配一个消息转换器——MappingJackson2HttpMessageConverter,该转换器可以将Java对象转换为Json格式的字符串响应到浏览器中

③ 将Java对象作为响应体信息:创建控制器方法,方法上添加@ResponseBody注解,方法返回值类型为实体类类型,即返回值为Java对象,此时该Java对象就会被转换成Json格式的字符串,最后在页面上打印出来的是Json格式的字符串

@RequestMapping("/testJson")
@ResponseBody
public User showTestJson() {
    return new User(1, "王小明", "男", 35);
}

💡 如果不做前两部操作(导入Json相关jar包以及开启注解驱动),直接在控制器方法中添加@ResponseBody注解并返回一个Java对象,即直接将Java对象作为响应体信息打印到页面上,页面会直接报500错误(服务器端错误)

④ 页面打印结果testJson

4.2 处理Ajax数据

① 创建测试超链接,超链接标签<a>添加@click属性,用于绑定单击事件

<div id="testAjaxId">
    <a @click="testAjax" th:href="@{/testAjax}">测试处理Ajax数据</a>
</div>

② 导入vue.js和axios.min.js文件,使用vue和axios处理超链接的点击事件

<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
<script type="text/javascript" th:src="@{/static/js/axios.min.js}"></script>
<script type="text/javascript">
    var vue = new Vue({
        el:"#testAjaxId",
        methods:{
            testAjax:function (event) {
                axios({
                    method:"post",
                    url:event.target.href,
                    params:{
                        username:"Key",
                        pwd:"123456"
                    }
                }).then(function (response) {
                    // 用警示框显示响应体的数据
                    alert(response.data);
                });
                // 阻止超链接的默认行为
                event.preventDefault();
            }
        }
    });
</script>

③ 创建控制器方法,方法上添加@ResponseBody注解,并添加两个形参,对应两个请求参数,返回值为响应体的信息

@RequestMapping("/testAjax")
@ResponseBody
public String showTestAjax(String username, String pwd) {
    System.out.println("用户名 --> " + username);
    System.out.println("密码 --> " + pwd);
    return "测试处理Ajax数据成功!";
}

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

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

相关文章

Docker 镜像构建可以分享的快乐

通过上一篇 Dockerfile 语法与指令的学习&#xff0c;本节就开始使用Dockerfile 来制作自己的 Docker 镜像啦。 Docker 镜像构建 新建 app.py 文件 from flask import Flaskapp Flask(__name__)app.route(/) def hello():return Hello World! Hogwarts.本代码主要功能是当我…

二十八—— 四十三

二十八、JavaScript——if-else语句 if-else语句- 语法&#xff1a; if(条件表达式) { 语句 }else{ 语句。。。 } - 执行流程 if-else执行时&#xff0c;先对条件表达式进行判断 如果结果为true,则执行if后得而语句 如果结果为false&#xff0c;则执行else后的语句 if-else if-…

公众号名称排名优化

HTML 实例解释 <p> 元素&#xff1a; <p>This is my first paragraph.</p> 这个 <p> 元素定义了 HTML 文档中的一个段落。 这个元素拥有一个开始标签 <p>&#xff0c;以及一个结束标签 </p>。 元素内容是&#xff1a;This is my firs…

生产环境LVM卷ext4文件系统故障修复处理

一、问题描述 某项目因存储视频流泪数据,数据量较大,生产环境当时已达158TB,采用LVM+Ext4存储,在某次LVM在线扩容过程中,扩容失败,报错:inode_counter 溢出,从字面看就i节点数量超过最大限制了,被lvresize命令忽略,报出警告:Invalid argument While checking for on…

Ac-GA-K(Ac)-AMC,577969-56-3

Ac- gak (Ac)-AMC&#xff0c;在蛋白酶偶联试验中测量组蛋白去乙酰化酶I类(HDAC 1、2、3和8)和II类(HDAC 6和10)活性的荧光底物。hdac催化Lys脱乙酰生成Ac-GAK-AM。 Ac-GAK(Ac)-AMC, fluorogenic substrate for measuring histone deacetylase class I (HDAC 1, 2, 3, and 8) a…

朴素二进制表示法

思路方案 在安全领域的研究中我们发现&#xff0c;很多数据预处理的步骤&#xff0c;在不同的场景下中都可以相互 借鉴&#xff0c;甚至可以进行直接复用。例如&#xff0c;对于加密流量相关的数据&#xff0c;当算法工程师 获取到一批加密流量的 pcap 包之后&#xff0c;不论他…

「Docker学习系列教程」基础篇小总结及高级篇预告

通过前面十来篇的学习&#xff0c;我们已经把docker基础篇学习完了。这篇文章&#xff0c;咱们就来小总结下基础篇学习的东西以及介绍接下来高级篇中&#xff0c;将会学习到哪些知识点。 基础篇总结&#xff1a; 第一篇&#xff0c; 凯哥就介绍了怎么在Centos系统中安装D…

【微服务之分布式全局Id】分布式全局ID生成

分布式全局ID解决方案 1、UUID 最容易想到的就是 UUID (Universally Unique Identifier) 了&#xff0c; UUID 的标准型式包含 32 个 16 进制数字&#xff0c;以连字号分为五段&#xff0c;形式为 8-4-4-4-12 的 36 个字符&#xff0c;这个是 Java 自带的&#xff0c;用着也简…

DBCO-PEG-Silane|DBCO-PEG-SIL|二苯并环辛炔-聚乙二醇-硅烷

DBCO-PEG-Silane&#xff0c;DBCO 试剂是一类点击化学标记试剂&#xff0c;含有非常活泼的 DBCO&#xff08;&#xff08;二苯并环辛炔&#xff09;基团&#xff0c;DBCO 试剂可以通过无铜点击化学与叠氮化物标记的分子或生物分子发生反应。DBCO 点击化学可以在水性缓冲液中运行…

用噪点滤镜回忆童年电视机的雪花屏

介绍 相信很多人80,90后的同学对童年里电视机的突然出现刺啦刺啦的雪花屏记忆犹新&#xff0c;本期将用 pixi.js 来完成一个电视机播放动漫然后突然出现雪花屏的动画&#xff0c;里面主要讲解了如何使用pixi.js播放帧动画和如何用噪点滤镜制造雪花屏。 演示 正文 初始化渲染…

web前端网页设计期末课程大作业:关于城市旅游的HTML网页设计 ——北京

&#x1f468;‍&#x1f393;学生HTML静态网页基础水平制作&#x1f469;‍&#x1f393;&#xff0c;页面排版干净简洁。使用HTMLCSS页面布局设计,web大学生网页设计作业源码&#xff0c;这是一个不错的旅游网页制作&#xff0c;画面精明&#xff0c;排版整洁&#xff0c;内容…

微服务框架 SpringCloud微服务架构 多级缓存 48 多级缓存 48.2 OpenResty 快速入门

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 多级缓存 文章目录微服务框架多级缓存48 多级缓存48.2 OpenResty 快速入门48.2.1 直接开干48 多级缓存 48.2 OpenResty 快速入门 48.2.1 直…

Linux(三) makefile与gdb调试

makefile mkefile文件中定义了一系列的规则来指定&#xff0c;哪些文件需要线编译&#xff0c;哪些后编译&#xff0c;哪些需要重新编译&#xff0c;甚至进行更复杂的功能操作&#xff0c;因为makefile就像一个Shell脚本一样&#xff0c;其中也可以执行操作系统的命令。 mkef…

java计算机毕业设计基于安卓Android的教学考勤系统APP

项目介绍 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设…

4个表格1个工具,解决客户的分类及管理

1897年&#xff0c;意大利经济学者帕累托发现&#xff1a;“社会上20%的人占有80%的社会财富”。 后来这一法则被发现可以适用到很多领域&#xff0c;包括客户管理。具体解释为“一家企业80%的收益来源于20%的客户”&#xff0c;即20%客户创造了企业80%的收益。 由于20%的客户…

分布式事务处理方案大 PK

[toc] 说好了写 TienChin 项目的&#xff0c;最近这个分布式事务算是一个支线任务吧&#xff0c;今天是再来一个短篇和小伙伴们总结一下分布式事务。 首先先说一个大原则&#xff1a;分布式事务能不用就不要用&#xff0c;毕竟这个用起来还是有一些麻烦的。当然&#xff0c;不…

B/S端界面控件DevExtreme内置的图标库介绍

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序&#xff0c;该套件附带功能齐…

闯关

我回来啦&#xff01;停更的几个月&#xff0c;我生了个娃。6.7斤的小虎妞&#xff0c;健健康康、白白胖胖。她现在已经五个多月了&#xff0c;能抬头、会翻身、会咯咯咯地笑、能拿住小玩具、还能摘我的眼镜……过程挺曲折的。不夸张地说&#xff0c;鬼门关溜达了一圈。好在&am…

邀请函小程序开发,减少设计制作局限性

随着社交平台和互联网技术的发展&#xff0c;很多产品的类型都在不断地发生着改变&#xff0c;就连邀请产品现在都出现了电子版的邀请函&#xff0c;颠覆了我们对于传统纸质邀请函的认知。无论是在日常生活学习还是工作中我们都会用到邀请函&#xff0c;而现在越来越多的人倾向…

Android逆向中常用工具和命令

Android逆向中常用工具和命令 Wifi ADB Google Store wifi ADB 当没有数据线时&#xff0c;可以开启wifiADB adb connect 192.168.0.101:5555开始食用 android 运行shell命令 https://github.com/termux/termux-app/releases ADB shell 截图 vim ~/.bash_profile curre…