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

后端常用技能:解决java项目前后端传输数据中文出现乱码、问号问题

0. 问题背景

最近做一个解析数据的小工具,本地运行时都正常,发布到服务器上后在导出文件数据时发现中文全部变成了问号,特此记录下问题解决的思路和过程

1. 环境

java 1.8
springboot 2.6.13
额外引入了fastjsoncommons-csv等依赖

2. 解决过程

思路1:后端响应体及前端blob对象声明编码格式为utf8

1、首先该问题在本地未发现,服务器上出现了,因此可以明确的是环境编码方式不一致导致的

2、一开始我以为在生成导出数据时出现的问题,项目涉及将导入的文本文件数据解析后导出为csv格式的excel数据

于是首先在导出时,在响应体中声明编码格式为utf8

response.setContentType("application/octet-stream;charset=utf-8");

同时我前端的处理,是将文件流数据转换为blob对象,然后进行文件下载,于是将生成blob对象的地方也声明编码格式

/*** 文件流转换为blob对象进行下载* @param data 后端返回的文件流数据* @param filename 文件名*/
function exportBlob(data, filename) {let blob = new Blob([data], {type: "application/octet-stream,charset=UTF-8"});// 创建一个下载链接const url = window.URL.createObjectURL(blob);// 创建一个隐藏的<a>元素,并设置其href属性为下载链接const a = document.createElement('a');a.href = url;a.download = filename;// 将<a>元素添加到页面中,并模拟点击document.body.appendChild(a);a.click();// 完成下载后,移除<a>元素和下载链接document.body.removeChild(a);window.URL.revokeObjectURL(url);
}

3、该方式本地运行正常,发布服务器后仍然有中文为问号的问题。于是继续分析

思路2:application.properties中设置全局编码格式

1、前面已经明确的是:服务器编码格式不一致导致的,于是通过locale指令查询服务器编码格式

在这里插入图片描述
如上图,发现服务器默认配置的编码格式是utf8

2、但结合实际情况,说明服务器编码格式肯定不是utf8,有时因为安装了一些额外的插件会导致服务器的编码格式被更改

同时怀疑数据在输入时就已经乱码了,于是在后端接口,接收输入参数时打印了数据,发现果然解析的中文就是问号,这就说明问题是出在前端传输给后端的数据中文乱码了,而不是后端返回给前端的数据乱码了。

在这里插入图片描述
3、怀疑是前后端的传输编码格式不统一导致的,于是在前端ajax请求中声明数据编码格式UTF-8

$.ajax({url: 'json/export',type: 'POST',contentType: "application/x-www-form-urlencoded;charset=UTF-8",data: {json: json},success: function (data, textStatus, xhr) {layer.close(load);if(data.msg != null){layer.msg(data.msg, {icon: 5});}else{exportBlob(data, "json转换输出数据.csv");layer.msg("导出成功");}},error: function (xhr, status, error) {layer.msg("导出失败");layer.close(load);console.log(xhr);}});

4、同时在后端声明编码格式,因为是springboot项目,所以直接在application.properties中配置:

server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
server.servlet.encoding.charset=UTF-8

因为我这里springboot版本是2.3+,低版本中应该是

spring.http.encoding.enabled=true
spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8

该配置可以让服务端在接收和发送数据时使用UTF-8编码

5、再次在服务器上运行,发现还是有中文乱码问题

6、怀疑该配置没生效,于是手写了一个配置类,用于声明编码格式

@Configuration
public class WebConfig implements WebMvcConfigurer
{@Beanpublic FilterRegistrationBean characterEncodingFilterRegistration() {FilterRegistrationBean registration = new FilterRegistrationBean(new CharacterEncodingFilter());registration.addInitParameter("encoding", "UTF-8");registration.addInitParameter("forceEncoding", "true");registration.addUrlPatterns("/*");return registration;}private static class CharacterEncodingFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {request.setCharacterEncoding("UTF-8");response.setContentType("text/html; charset=UTF-8");chain.doFilter(request, response);}}
}

7、服务器上运行,问题还是没解决,说明不是该问题导致

思路3:重新编码传输数据

1、如上我们已经将服务端编码格式设置为utf8了,解析仍然有问题,于是尝试将传入数据二次编码

导入文件解析:

InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.ISO_8859_1);

字符串参数解析:

json = new String(json.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);

2、然后本地运行,发现就出现问题了,本地运行也出现中文乱码了,那么说明编码格式ISO_8859_1肯定不行

3、于是尝试根据环境本身的编码格式去设置

打印了下服务器上的编码格式

log.error("编码:"+ Charset.defaultCharset().name());

服务器打印结果
在这里插入图片描述
这里就可以看到服务器上编码果然不是utf8,于是重新设置编码:

 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.defaultCharset());            
json = new String(json.getBytes(Charset.defaultCharset()), StandardCharsets.UTF_8);

4、服务器上运行,依然出现中文乱码

思路4:jvm启动脚本中添加-Dfile.encoding=utf-8

1、目前我们能确定的是服务器的编码格式不是utf8,而是US-ASCII。但在代码中二次编码的形式行不通,这里思路有些阻塞了。可以明确的就是环境编码格式导致的,但是怎么定义环境的编码格式呢? 从项目内部定义的形式似乎都行不通

2、自己思路阻塞的时候一般有两种解决办法:
(1)放一放,过几个小时或者第二天再来看,这是思路清空,相对受之前惯性思维的影响较小,一般这时再来看有奇效
(2)与其他人讨论,融合新的思路

3、这里因为想当天把这个问题解决了,于是采取了第二种与同事进行了交流,刚好同事给我说他之前遇到过一种中文乱码的情况,通过在启动脚本里设置-Dfile.encoding=utf-8解决的

于是进行了尝试,在java项目的启动脚本的添加了该配置

JAVA_OPTS="-server -Xms1G -Xmx2G -Xmn256m -Xss1m \
-Dfile.encoding=utf-8 \
-XX:SurvivorRatio=4 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection \
-XX:CMSInitiatingOccupancyFraction=60 -XX:+PrintGCDateStamps \
-XX:+PrintGCDetails -Xloggc:$LOGS_DIR/gc.log"

4、重启项目,发现中文显示正常了,同时打印的编码格式也变成utf8了。问题解决

5、这里再回过头来看时,发现确实是自己思路陷入局限了,明明知道是环境的问题,却一直期望通过项目内配置解决。

实际上java通过jvm运行,其环境编码问题,自然应该从jvm配置着手。

-Dfile.encoding=utf-8的作用就是设置jvm虚拟机的编码格式,java项目默认字符集是在java虚拟机启动时决定的,依赖于java虚拟机所在的操作系统的区域以及字符集

实际上该配置应该作为我们项目的常用配置,此次也是因为临时做个新工具,忽略了该配置的书写

总结

如上,就是我针对java项目出现中文乱码的问题的解决思路及过程,对比了网上说明的解决方法,发现也基本上涵盖了大多数情况,大家可以参考

相关文章:

后端常用技能:解决java项目前后端传输数据中文出现乱码、问号问题

0. 问题背景 最近做一个解析数据的小工具&#xff0c;本地运行时都正常&#xff0c;发布到服务器上后在导出文件数据时发现中文全部变成了问号&#xff0c;特此记录下问题解决的思路和过程 1. 环境 java 1.8 springboot 2.6.13 额外引入了fastjson&#xff0c;commons-csv等…...

SpringBoot中使用MongoDB

目录 搭建实体类 基本的增删改查操作 分页查询 使用MongoTemplate实现复杂的功能 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> 在ap…...

【TS】入门

创建项目 vscode自动编译ts 生成配置文件 tsc --init 然后发现终端也改变了&#xff1a;...

Apache ECharts

Apache ECharts介绍&#xff1a; Apache ECharts 是一款基于 Javascript 的数据可视化图表库&#xff0c;提供直观&#xff0c;生动&#xff0c;可交互&#xff0c;可个性化定制的数据可视化图表。 官网地址&#xff1a;https://echarts.apache.org/zh/index.html Apache ECh…...

超详细的胎教级Stable Diffusion使用教程(四)

这套课程分为五节课&#xff0c;会系统性的介绍sd的全部功能和实操案例&#xff0c;让你打下坚实牢靠的基础 一、为什么要学Stable Diffusion&#xff0c;它究竟有多强大&#xff1f; 二、三分钟教你装好Stable Diffusion 三、小白快速上手Stable Diffusion 四、Stable dif…...

串口属性中的BM延时计时器问题

如果使用程序修改则需要修改注册表对应位置如下 第一个示例&#xff08;217&#xff09; 第二个示例&#xff08;219&#xff09; 需要注意的事情是修改前必须点查看串口名称&#xff08;例如上图是com5&#xff09; 程序修改&#xff1a; 有没有办法以编程方式更改USB <…...

PyQt6--Python桌面开发(8.QPlainTextEdit纯文本控件)

QPlainTextEdit纯文本控件...

Java | Leetcode Java题解之第83题删除排序链表中的重复元素

题目&#xff1a; 题解&#xff1a; class Solution {public ListNode deleteDuplicates(ListNode head) {if (head null) {return head;}ListNode cur head;while (cur.next ! null) {if (cur.val cur.next.val) {cur.next cur.next.next;} else {cur cur.next;}}return…...

重生奇迹mu再生宝石怎么用有什么用

重生奇迹mu再生宝石有2个用处&#xff1a; 1、在玛雅哥布林处给380装备加PVP属性4追4以上的380级装备,守护宝石一颗,再生宝石一颗,成功得到PVP装备,失败宝石消失,装备无变化&#xff1b; 2、给非套装点强化属性用法跟祝福,灵魂,生命一样直接往装备上敲,成功得到随机强化属性一…...

pdf 文件版面分析--pdfplumber (python 文档解析提取)

pdfplumber 的特点 1、它是一个纯 python 第三方库&#xff0c;适合 python 3.x 版本 2、它用来查看pdf各类信息&#xff0c;能有效提取文本、表格 3、它不支持修改或生成pdf&#xff0c;也不支持对pdf扫描件的处理 import glob import pdfplumber import re from collection…...

PostgreSQL的学习心得和知识总结(一百四十三)|深入理解PostgreSQL数据库之Support event trigger for logoff

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…...

https免费证书获取

获取免费证书的网址&#xff1a; Certbot 1. 进入你的linux系统&#xff0c;先安装snapd&#xff0c; yum install snapd 2. 启动snapd service snapd start 3.安装 Certbot snap install --classic certbot 注意如下出现此错误时&#xff0c;需要先建立snap 软连接后&am…...

C语言 | Leetcode C语言题解之第74题搜索二维矩阵

题目&#xff1a; 题解&#xff1a; bool searchMatrix(int** matrix, int matrixSize, int* matrixColSize, int target) {int m matrixSize, n matrixColSize[0];int low 0, high m * n - 1;while (low < high) {int mid (high - low) / 2 low;int x matrix[mid /…...

杰发科技AC7840——软件Sent_HAL39X

0. 序 使用PWM模拟Sent测试下7840的软件sent功能。 参考链接&#xff1a;SENT协议应用笔记 - TechPlus汽车工坊的文章 - 知乎 SENT协议 1. Sent功能测试 使用提供的软件Sent代码在7840上测试&#xff0c;接收数据OK 2. 参考资料 3. 数据解析 我们个根据上述参考资料尝试解析…...

IOS 开发 - block 使用详解

1.Blobk的定义 block的写法相对难记,不必司机应被,只需要在xcode里打出"inlineBlock"--回车, 系统会自动帮你把基础版写法给你匹配出来 //Block的基础声明//等号""之前是blobk的声明,等号“”后面是block的实现/*returnType:返回类型(void、int、String *…...

BUU-[极客大挑战 2019]Http

考察点 信息收集 http构造请求数据包 题目 解题步骤 参考文章&#xff1a;https://zhuanlan.zhihu.com/p/367051798 查看源代码 发现有一个a标签&#xff0c;但是οnclick"return false"就是点击后不会去跳转到Secret.php的页面 所以我就自己拼接url http://no…...

开发Web3 ETF的技术难点

开发Web3 ETF&#xff08;Exchange-Traded Fund&#xff0c;交易所交易基金&#xff09;软件时&#xff0c;需要注意以下几个关键问题。开发Web3 ETF软件是一个复杂的过程&#xff0c;涉及到金融、法律和技术多个领域的专业知识。开发团队需要综合考虑上述问题&#xff0c;以确…...

【K8s】Kubectl 常用命令梳理

Kubectl常用命令梳理 下面包含大致涵盖命令只需要替换对应的Pod \ NameSpace 查看 命名空间 是 ’worktest2‘ 下 名字包括 ’todo‘的所有 Pod kubectl -n worktest2 get pod|grep todo查看 所有命名空间下 名字包括 ’todo‘的所有 Pod kubectl get pods --all-namespace…...

机器学习-监督学习

监督学习是机器学习和人工智能中的一个重要分支&#xff0c;它涉及使用已标记的数据集来训练算法&#xff0c;以便对数据进行分类或准确预测结果。监督学习的核心在于通过输入数据&#xff08;特征&#xff09;和输出数据&#xff08;标签或类别&#xff09;之间的关系&#xf…...

搭建Docker私服镜像仓库Harbor

1、概述 Harbor是由VMware公司开源的企业级的Docker Registry管理项目&#xff0c;它包括权限管理(RBAC)、LDAP、日志审核、管理界面、自我注册、镜像复制和中文支持等功能。 Harbor 的所有组件都在 Dcoker 中部署&#xff0c;所以 Harbor 可使用 Docker Compose 快速部署。 …...

基于粒子群优化算法的地表水源热泵机组优化调度 以水源热泵机组角度对地表水源热泵系统建模

基于粒子群优化算法的地表水源热泵机组优化调度 以水源热泵机组角度对地表水源热泵系统建模&#xff0c; 并采用粒子群优化算法优化算法求解热泵机组每小时最佳制冷量和制热量 最近帮朋友做了个小区地表水源热泵的调度优化项目&#xff0c;一开始以为就是调调空调温度&#xf…...

CHORD-X从零开始:C语言基础概念学习报告自动生成教程

CHORD-X从零开始&#xff1a;C语言基础概念学习报告自动生成教程 你是不是也遇到过这样的烦恼&#xff1f;作为编程老师&#xff0c;每次讲完C语言的指针、结构体这些难点&#xff0c;总想给学生一份清晰易懂的复习报告&#xff0c;但自己动手整理又太花时间。或者&#xff0c…...

WavePWM库:嵌入式LED正弦调光算法与实现

1. WavePWM库概述&#xff1a;正弦波形LED调光的底层实现原理与工程应用 WavePWM是一个面向嵌入式LED驱动场景的轻量级波形PWM计算库&#xff0c;其核心价值不在于直接控制硬件引脚&#xff0c;而在于 以确定性数学模型生成高保真度的正弦&#xff08;或类正弦/指数&#xff0…...

用Rust还是JavaScript?Tauri 2.0系统托盘开发的两种姿势与选型建议

Tauri 2.0系统托盘开发&#xff1a;Rust与JavaScript的技术选型深度解析 当桌面应用需要常驻后台运行时&#xff0c;系统托盘功能便成为用户体验的关键组件。Tauri 2.0作为新一代跨平台桌面框架&#xff0c;允许开发者在前端JavaScript与后端Rust两种技术栈中实现这一功能。本文…...

告别标注烦恼:用DINOv2自监督模型,在Intel Image数据集上3个epoch实现93%准确率

零标注成本实战&#xff1a;DINOv2自监督模型在Intel Image数据集上的高效迁移方案 当我在实验室第一次尝试用传统方法训练一个图像分类模型时&#xff0c;面对数千张需要手动标注的图片&#xff0c;几乎要放弃这个课题。直到发现了自监督学习这个宝藏领域——特别是DINOv2这样…...

算法优化中的寄存器重用与内存映射策略的技术6

寄存器重用与内存映射策略在算法优化中的重要性寄存器重用和内存映射是提升计算密集型算法性能的关键技术&#xff0c;通过减少数据访问延迟和优化存储层次结构的使用&#xff0c;显著提高执行效率。寄存器重用的核心方法与技术数据局部性利用 通过循环展开&#xff08;Loop Un…...

天津专业的阀门厂排名

在天津&#xff0c;阀门行业发展态势良好&#xff0c;众多阀门厂各有特色与优势。中国通用机械工业协会最新发布的《2026年阀门行业高质量发展白皮书》显示&#xff0c;天津的阀门产业在技术创新、产品质量和市场份额等方面都有不错的表现。下面为大家介绍几家天津比较知名的阀…...

AT32F435_437_USB_MSC_SDIO:实现高效SD卡U盘功能的开发指南

1. 从零开始&#xff1a;AT32F435/437的USB MSC功能初探 第一次接触AT32F435/437的USB大容量存储设备(MSC)功能时&#xff0c;我完全被它的实用性惊艳到了。想象一下&#xff0c;你的嵌入式设备突然变身成电脑上的U盘&#xff0c;可以直接拖拽文件读写SD卡&#xff0c;这对数据…...

移动端语音交互避坑指南:录音超时截取、倒计时提醒与MP3转换的完整方案

移动端语音交互避坑指南&#xff1a;录音超时截取、倒计时提醒与MP3转换的完整方案 在即时通讯和语音输入场景中&#xff0c;流畅的录音体验直接影响用户留存。数据显示&#xff0c;超过83%的用户会因为录音功能卡顿或操作复杂而放弃使用语音功能。本文将深入解析三个关键体验优…...

从串口通信到内存总线:手把手拆解‘波特率’、‘比特率’与‘总线带宽’的异同与实战计算

从串口通信到内存总线&#xff1a;深度解析波特率、比特率与总线带宽的实战差异 在嵌入式开发和计算机体系结构领域&#xff0c;数据传输速率的计算是工程师日常工作中无法绕开的基础技能。但令人困惑的是&#xff0c;同样的"速率"概念在不同场景下却有着完全不同的…...