SpringMVC系列十: 中文乱码处理与JSON处理
文章目录
- 中文乱码处理
- 自定义中文乱码过滤器
- Spring提供的过滤器处理中文
- 处理json和HttpMessageConverter<T>
- 处理JSON-@ResponseBody
- 处理JSON-@RequestBody
- 处理JSON-注意事项和细节
- HttpMessageConverter<T\>
- 文件下载-ResponseEntity<T\>
- 作业布置
上一讲, 我们学习的是 SpringMVC系列九: 数据格式化与验证及国际化
现在打开springmvc项目

中文乱码处理
自定义中文乱码过滤器
●说明
当表单提交数据为中文时, 会出现乱码,我们来解决一下( 提示: 想恢复name属性的绑定)


1.创建过滤器 JavaWeb过滤器
在com.zzw.web.filter包下新建MyCharacterFilter
/*** @author 赵志伟* @version 1.0* 编写过滤器, 处理中文乱码*/
@SuppressWarnings({"all"})
public class MyCharacterFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {//这里加入对编码的处理servletRequest.setCharacterEncoding("utf-8");//放行请求, 这个规则和前面见过的java web过滤器一样filterChain.doFilter(servletRequest, servletResponse);}@Overridepublic void destroy() {}
} 2.在web.xml中配置.
注意: 不要乱写, 过滤器一般写在web.xml的最上面, 多个过滤器之间会形成过滤器链, 要注意顺序.
<!--配置处理中文乱码的过滤器
拦截所有请求, 处理编码.把过滤器配置到web.xml前面-->
<filter><filter-name>MyCharacterFilter</filter-name><filter-class>com.zzw.web.filter.MyCharacterFilter</filter-class>
</filter>
<filter-mapping><filter-name>MyCharacterFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
3.完成测试.


Spring提供的过滤器处理中文
1.修改web.xml, 换成Spring提供的过滤器, 处理中文乱码.
<!--配置Spring提供的过滤器, 解决中文乱码问题-->
<filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param>
</filter>
<filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
2.完成测试


处理json和HttpMessageConverter
处理JSON-@ResponseBody
●说明
项目开发中, 我们往往需要服务器返回的数据格式是按照json来返回的, 我们看一下SpringMVC是如何处理的,
●应用案例
1.引入处理json需要的jar包, 注意spring5.x 需要使用jackson-2.9.x.jar的包springmvc处理json需要jar
2.在web路径下创建json.jsp
<head><title>json提交</title><%--引入jquery--%><%--编写jquery代码和请求--%>
</head>
<body>
<h1>请求一个json数据</h1>
<a href="?" id="getJson">点击获取json数据</a>
</body>
3.在com.zzw.web.json.entity包 下新建 Dog.java
public class Dog {private String name;private String address;//全参构造器, 无参构造器, setter,getter,toString方法
}
4.在json包 下新建JsonHandler.java
@Controller
public class JsonHandler {/*** 解读* 1.目标方法 @ResponseBody, 表示返回的数据是json格式* 2.springmvc底层根据目标方法@ResponseBody, 返回指定格式,* 3.底层原理我们在前面自定义@ResponseBody讲过, 这里原生的springmvc使用转换器* 4.HttpMessageConverter [一会我们debug]* @return*/@RequestMapping(value = "/json/dog")@ResponseBodypublic Dog getJson() {//返回对象//springmvc会根据你的设置, 转成json格式数据返回Dog dog = new Dog();dog.setName("大黄");dog.setAddress("蜡笔小新");return dog;}
}
5.回填json.jsp的action
<html>
<head><title>json提交</title><%--引入jquery--%><script type="text/javascript" src="script/jquery-3.6.0.min.js"></script><%--编写jquery代码和请求--%><script type="text/javascript">$(function () {//给id="getJson"绑定一个点击事件$("#getJson").click(function () {console.log("ok");//测试一下let url = this.href;//this是dom对象let args = {"time": new Date};//这老师要发送数据, 为了防止页面缓存$.post(url,args,function(data) {//data就是后台返回的数据, 是json格式console.log("data=", data);console.log("name=", data.name);console.log("address=", data.address);},"json")return false;//这里我们返回false, 就不使用href默认机制});})</script>
</head>
<body>
<h1>请求一个json数据</h1>
<%--处理
1.当用户点击超链接时, 我们发出一个ajax请求
2.接收到请求后, 我们查看这个数据
3.使用我们前面见过的jquery发出ajax请求的知识
--%>
<a href="<%=request.getContextPath()%>/json/dog" id="getJson">点击获取json数据</a>
</body>
</html>
6.完成测试(浏览器)

7.用postman完成测试

处理JSON-@RequestBody
●应用案例
-前面我们是通过表单, 或者 url请求携带 参数=参数值 把数据提交给目标方法
1)给大家举例客户端发送 json字符串数据
2)使用SpringMVC的 @RequestBody 将客户端提交的json数据, 封装成JavaBean对象
3)再把这个javabean以json而对象形式返回
4)完成效果示意图 [空]
1.修改json.jsp, 增加发送json数据代码
<html>
<head><title>json提交</title><%--引入jquery--%><script type="text/javascript" src="script/jquery-3.6.0.min.js"></script><%--编写jquery代码和请求--%><script type="text/javascript">$(function () {//....//绑定按钮点击事件, 提交json数据//springmvc 可以在后台将json转成对象$("button[name='butt1']").click(function () {//todo 具体的业务代码以后再写})})</script>
</head>
<body>
<%--.....--%>
<h1>发出一个json数据</h1>
u:<input id="username" type="text"/><br/>
a:<input id="age" type="text"/><br/>
<button name="butt1">添加用户</button>
</body>
</html>
2.在com.zzw.web.json.entity包 下新建 User.java
public class User {private String userName;private Integer age;//全参构造器, 无参构造器, setter,getter,toString方法
}
3.修改JsonHandler.java, 增加处理json代码. 注意: 老韩用的是 @PostMapping, 等价: @RequestMapping(method = RequestMethod.POST)
@Controller
public class JsonHandler {//...@RequestMapping(value = "/save2")@ResponseBodypublic User save2(User user) {//将前台传过来的数据, 以json的格式返回给浏览器System.out.println("user=" + user);return user;}
}
4.回填json.jsp
//绑定按钮点击事件, 提交json数据
//springmvc 可以在后台将json转成对象
$("button[name='butt1']").click(function () {//目标:将userName 和 age 封装成json字符串let url = "/springmvc/save2";let userName = $("#userName").val();let age = $("#age").val();//将json对象转成json字符串let args = JSON.stringify({"userName": userName, "age": age});$.ajax({url: url,type: "POST",data: args,success(data) {console.log("返回的data=", data);},//下面这个contentType参数, 是指定发送数据时的编码和格式//只有$.ajax才有, $.post没有contentType: "application/json;charset=utf-8"})
})
5.测试. 数据为空

后台. 数据为空

6.加上 @RequestBody注解
/*** 老师解读* 1. @RequestBody User user 在形参指定了 @RequestBody* 2. springmvc就会将提交的json字符串数据填充给指定Javabean* @param user* @return*/
@RequestMapping(value = "/save2")
@ResponseBody
public User save2(@RequestBody User user) {//将前台传过来的数据, 以json的格式返回给浏览器System.out.println("user=" + user);return user;
}
7.测试

后台

8.postman测试
postman提交json格式的数据


处理JSON-注意事项和细节
1.目标方法正常返回JSON需要的数据, 可以是一个对象, 也可以是一个集合
2.前面我们讲的是返回一个Dog对象->转成Json数据格式返回
●应用实例
JsonHandler.java添加如下方法
//编写方法, 以json格式返回多个Dog
@RequestMapping(value = "/json/dogs")
@ResponseBody
public List<Dog> getJsons() {List<Dog> dogs = new ArrayList<>();dogs.add(new Dog("大黄", "蜡笔小新之家"));dogs.add(new Dog("大黄2", "蜡笔小新之家2"));dogs.add(new Dog("大黄3", "蜡笔小新之家3"));return dogs;
}
postman测试

返回结果

3.@ResponseBody 可以直接写在controller上, 这样对所有方法都生效
●应用实例

完成测试
后台数据

postman测试

4.@ResponseBody + @Controller 可以直接写成 @RestController, 我们看一下源码

测试


HttpMessageConverter<T>
●基本说明
SpringMVC处理 JSON- 底层实现是依靠 HttpMessageConverter<T> 来进行转换的
●工作机制简图

●处理JSON-底层实现(HttpMessageConverter<T>)
1.使用 HttpMessageConverter<T> 将请求信息转化并绑定到处理方法的入参中, 或将响应结果转为对应类型的相应信息, Spring 提供了两种途径:
√ 使用 @RequestBody / @ResponseBody 对目标方法进行标注
√ 使用 @HttpEntity<T> / ResponseEntity<T> 作为目标方法的入参或返回值
2.当控制器处理方法使用到 @RequestBody / @ResponseBody 或 HttpEntity<T> / ResponseEntity<T> 时, Spring 首先根据请求头或响应头的 Accept 属性选择匹配的 HttpMessageConverter, 进而根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter, 若找不到可用的 HttpMessageConverter 将报错
Debug 源码-梳理一下


一. 将请求信息转化并绑定到处理方法的入参中







二. 将响应结果转为对应类型的相应信息



文件下载-ResponseEntity<T>
●说明
在SpringMVC中, 通过返回 ResponseEntity<T> 的类型, 可以实现文件下载的功能
●案例演示
准备工作: 在web路径/img下准备一个要下载的文件, 比如图片: 1.jpg

1.修改json.jsp
<h1>下载文件的测试</h1>
<a href="?">点击下载文件</a>
2.修改JsonHandler.java, 增加方法
//响应银狐下载文件的请求
@RequestMapping(value = "/downFile")
public ResponseEntity<byte[]> downFile(HttpSession session) throws Exception {//1.先获取到下载文件的inputStreamInputStream inputStream = session.getServletContext().getResourceAsStream("/img/1.jpg");//2.开辟一个存放文件的字节数组, 这里我们使用byte[] 是可以支持二进制数据(图片, 视频, 音频, doc文档)byte[] bytes = new byte[inputStream.available()];//3.将下载文件的数据, 读入到byte[]inputStream.read(bytes);/*public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, HttpStatus status) {this(body, headers, (Object) status);}*///4.创建返回的HttpStatusHttpStatus status = HttpStatus.OK;//5.创建 headersHttpHeaders headers = new HttpHeaders();//指定返回的数据, 客户端应当以附件形式处理headers.add("Content-Disposition", "attachment;filename=1.jpg");//构建一个ResponseEntity 对象ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, status);//如果出现找不到文件, 解决方法 rebuild project return responseEntity;
}
文件下载响应头的设置
content-type 指示响应内容的格式
content-disposition 指示如何处理响应内容
一般有两种方式:
inline: 直接在页面显示
attchment: 以附件形式下载
3.回填json.jsp
<a href="<%=request.getContextPath()%>/downFile">点击下载文件</a>
4.完成测试
页面方式

postman测试, 返回二进制数据, 因为postman没有对数据进行解析

作业布置
1.把我们前面学过的数据格式化, 验证以及国际化, Json处理, 文件下载, 相关代码和案例, 自己写一遍. 一定要写一遍, 否则没有印象, 理解不会渗入
2.把Debug过的HttpMessageConverter源码, 自己再走一下, 加深理解(不用每条语句, 都debug, 找流程…)
3.DataBinder工作机制-将示意图画出
4,Debug一下validate得到验证errors信息, 加深理解(不用每一条语句都debug, 找流程)

下一讲, 我们学习 SpringMVC系列九: 数据格式化与验证及国际化
相关文章:
SpringMVC系列十: 中文乱码处理与JSON处理
文章目录 中文乱码处理自定义中文乱码过滤器Spring提供的过滤器处理中文 处理json和HttpMessageConverter<T>处理JSON-ResponseBody处理JSON-RequestBody处理JSON-注意事项和细节HttpMessageConverter<T\>文件下载-ResponseEntity<T\>作业布置 上一讲, 我们学…...
使用MyBatisPlus进行字段的自动填充
使用MyBatisPlus进行字段的自动填充 需求场景 当我们往数据库里面插入一条数据,或者是更新一条数据时,一般都需要标记创建时间create_time和更新时间update_time的值,但是如果我们每张表的每个请求,在执行sql语句的时候我们都手…...
python爬虫之aiohttp多任务异步爬虫
python爬虫之aiohttp多任务异步爬虫 爬取的flash服务如下: from flask import Flask import timeapp Flask(__name__)app.route(/bobo) def index_bobo():time.sleep(2)return Hello boboapp.route(/jay) def index_jay():time.sleep(2)return Hello jayapp.rout…...
1964springboot VUE小程序在线学习管理系统开发mysql数据库uniapp开发java编程计算机网页源码maven项目
一、源码特点 springboot VUE uniapp 小程序 在线学习管理系统是一套完善的完整信息管理类型系统,结合springboot框架uniapp和VUE完成本系统,对理解vue java编程开发语言有帮助系统采用springboot框架(MVC模式开发),…...
【前端项目笔记】3 用户管理
用户管理相关功能实现 涉及表单、对话框、Ajax数据请求 基本页面 用户列表开发 在router.js中导入Users.vue 解决用户列表小问题 选中(激活)子菜单后刷新不显示高亮 给二级菜单绑定单击事件,点击链接时把对应的地址保存到sessionSto…...
【文献及模型、制图分享】基于SSP-RCP不同情景的京津冀地区土地覆被变化模拟
公众号新功能 目前公众号新增以下等功能 1、处理GIS出图、Python制图、区位图、土地利用现状图、土地利用动态度和重心迁移图等等 2、核密度分析、网络od分析、地形分析、空间分析等等 3、地理加权回归、地理探测器、生态环境质量指数、地理加权回归模型影响因素分析、计算…...
基于单片机的智能台灯控制系统
摘要: 文章设计一款单片机智能台灯控制系统,实现对台灯的手动和自动控制功能,以 STC89C52 单片机作为多功能智能台灯的主控制器,光电检测模块检测坐姿,红外传感器检测人体,光敏电阻检测光强,同…...
PrestaShop的一些使用介绍
目录 PrestaShop 是一个功能丰富的开源电子商务解决方案。 1. 以下是其基本概念和架构的一些要点: 2. PrestaShop 的模块开发是扩展其功能的重要方式。以下是对 PrestaShop 模块开发的详细介绍: 开发环境准备: 3. PrestaShop 的模块开发允…...
零基础女生如何入门人工智能,从哪里下手?学习时间大概要多久?
作为一个理工科早期毕业生,出于近乎本能的敏感,格外关注全网热议的ChatGPT。 本来国内就业环境就不好,各行各业内卷越来越严重,加上人工智能的异军突起,各行各业势必将迎来科技进步跨时代的巨大冲击,在此情…...
简答分享python学习进修网站
一、网战推荐 CodeCombat 是一款网页编程游戏。这款编程游戏借鉴了游戏很多设计元素,游戏剧情十分丰富。Codecombat能够学习Python多种语言,这些语言能够运用到游戏设计、网页应用、app的开发上。 Checkio 是一个基于浏览器的游戏,你需要使…...
linux高级编程(I/O)
fputc int fputc(int c, FILE *stream); 功能: 向流中写入一个字符 参数: c:要写入的字符 stream:文件流指针 返回值: 成功返回写入的字符ASCII码值 失败返回EOF fgetc int fgetc(FILE *stream); 功能: 从流中读取一个字符 参数: stream:文件流…...
Java面试——认证与授权
X、常见面试题汇总 1、Shiro与SpringSecutity对比 1)Shiro的特点: Shiro 是 Apache 下的项目,相对简单、轻巧,更容易上手使用。 Shiro 权限功能基本都能满足,单点登录都可以实现。且不用与任何的框架或者容器绑定, 可…...
【经典算法OJ题讲解】
1.移除元素 经典算法OJ题1: 移除元素 . - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/remove-element/desc…...
大数据面试题之Zookeeper面试题
目录 1、介绍下Zookeeper是什么? 2、Zookeeper有什么作用?优缺点?有什么应用场景? 3、Zookeeper的选举策略,leader和follower的区别? 4、介绍下Zookeeper选举算法 5、Zookeeper的节点类型有哪些?分别作用是什么? 6、Zookeeper的节点数怎么设置比较好? …...
JVM 内存区域
一、运行时数据区域 Java 虚拟机在执行 Java 程序的过程中,会把它管理的内存划分成若干个不同的数据区域。 JDK 1.8 和之前的版本略有不同,这里介绍 JDK 1.7 和 JDK 1.8 两个版本。 JDK 1.7: 线程私有: 程序计数器虚拟机栈本地…...
全网最强剖析Spring AOP底层原理
相信各位读者对于Spring AOP的理解都是一知半解,只懂使用,却不懂原理。网上关于Spring AOP的讲解层出不穷,但是易于理解,让人真正掌握原理的文章屈指可数。笔者针对这一痛点需求,决定写一篇关于Spring AOP原理的优质博…...
Vscode中的行尾序列CRLF/LF不兼容问题
最近开发的的时候,打开项目文件经常会出现爆红错误提示信息,显示如下图: 这东西太烦人了,毕竟谁都不希望在遍地都是爆红的代码里写东西,就像能解决这个问题,根据提示可以知道这是vscode中使用的prettier插件…...
常见加密方式:MD5、DES/AES、RSA、Base64
16/32位的数据,最有可能就是使用md5加密的 使用对称加密的时候,双方使用相同的私钥 私钥:单独请求/隐藏在前端的隐藏标签当中 二、RSA非对称密钥加密 公钥加密,私钥解密 私钥是通过公钥计算生成的 加密解密算法都在js源文件当…...
如何在 C++/Qt/CMake 项目中构建 Rust 代码
问题描述 我有一个使用 CMake 构建的现有 C/Qt 项目,我想开始添加 Rust 代码,并能够从主 C 代码库中调用这些 Rust 代码。应该如何组织项目结构? 现有项目结构 ./CMakeLists.txt ./subproject-foo/CMakeLists.txt ./subproject-foo/src/..…...
封装了一个优雅的iOS转场动画
效果图 代码 // // LBTransition.m // LBWaterFallLayout_Example // // Created by mac on 2024/6/16. // Copyright © 2024 liuboliu. All rights reserved. //#import "LBTransition.h"interface LBPushAnimation:NSObject<UIViewControllerAnimated…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...
ubuntu中安装conda的后遗症
缘由: 在编译rk3588的sdk时,遇到编译buildroot失败,提示如下: 提示缺失expect,但是实测相关工具是在的,如下显示: 然后查找借助各个ai工具,重新安装相关的工具,依然无解。 解决&am…...
嵌入式面试常问问题
以下内容面向嵌入式/系统方向的初学者与面试备考者,全面梳理了以下几大板块,并在每个板块末尾列出常见的面试问答思路,帮助你既能夯实基础,又能应对面试挑战。 一、TCP/IP 协议 1.1 TCP/IP 五层模型概述 链路层(Link Layer) 包括网卡驱动、以太网、Wi‑Fi、PPP 等。负责…...
