当前位置: 首页 > 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 快速部署。 …...

SpringBoot自定义初始化sql文件 支持多类型数据库

我在resources目录下有init.sql初始化sql语句 指定sql文件的地址 sql内容如下&#xff1a; /*角色表*/ INSERT INTO #{schema}ccc_base_role (id, create_time, create_user_id, is_delete, role_name, status, update_time, update_user_id) VALUES(b89e30d81acb88448d412…...

nginx--FastCGI

CGI 概念 nginx通过与第三方基于协议实现&#xff0c;即通过某种特定协议将客户端请求转发给第三方服务处理&#xff0c;第三方服务器会新建新的进程处理用户的请求&#xff0c;处理完成后返回数据给Nginx并回收进程(下次处理有需要新建)&#xff0c;最后nginx在返回给客户端…...

【数据结构】浅谈

✨✨✨专栏&#xff1a;数据结构 &#x1f9d1;‍&#x1f393;个人主页&#xff1a;SWsunlight 目录 一、概念&#xff1a; 二、物理结构&#xff1a; 1、顺序存储结构&#xff1a; 2、链式存储结构&#xff1a; 3、数据索引存储结构: 4、数据散列存储结构&#xf…...

简洁大气APP下载单页源码

源码介绍 简洁大气APP下载单页源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 效果截图 源码下载 简洁大气APP下载单页源码...

ICode国际青少年编程竞赛- Python-4级训练场-复杂嵌套for循环

ICode国际青少年编程竞赛- Python-4级训练场-复杂嵌套for循环 1、 for i in range(4):Dev.step(i6)for j in range(3):Dev.turnLeft()Dev.step(2)2、 for i in range(4):Dev.step(i3)for j in range(4):Dev.step(2)Dev.turnRight()Dev.step(-i-3)Dev.turnRight()3、 for i …...

Idea入门:一分钟创建一个Java工程

一&#xff0c;新建一个Java工程 1&#xff0c;启动Idea后&#xff0c;选择 [New Project] 2&#xff0c;完善工程信息 填写工程名称&#xff0c;根据实际用途取有意义的英文名称选择Java语言&#xff0c;可以看到还支持Kotlin、Javascript等语言选择包管理和项目构建工具Mav…...

QGraphicsView实现简易地图8『缓存视口周边瓦片』

前文链接&#xff1a;QGraphicsView实现简易地图7『异步加载-多瓦片-无底图』 前7篇的地图加载&#xff0c;都采用最少瓦片数量的算法&#xff0c;即用最少数量的瓦片覆盖视口&#xff0c;以获得最快的加载速度。但是这样会带来一个问题&#xff0c;那就是每当移动地图时&#…...

如何在Java项目中使用Spring Boot快速连接达梦数据库(DM)

前言 在Java开发领域&#xff0c;Spring Boot凭借其简洁快速的特性成为现代应用开发的首选框架。本文将详细介绍如何在Spring Boot项目中整合JDBC以快速连接达梦数据库(DM)&#xff0c;并提供一个简单的示例来验证连接是否成功。 一、环境准备与依赖配置 在开始之前&#xf…...

QT中的容器

Qt中的容器 关于Qt中的容器类&#xff0c;下面我们来进行一个总结&#xff1a; Qt的容器类比标准模板库&#xff08;STL&#xff09;中的容器类更轻巧、安全和易于使用。这些容器类是隐式共享和可重入的&#xff0c;而且他们进行了速度和存储的优化&#xff0c;因此可以减少可…...

安卓手机APP开发__屏幕兼容性概述

安卓手机APP开发__屏幕兼容性概述 目录 概述 屏幕大小 灵活的布局 备选的布局 可改写的图像 像素的深度 深度依赖 备选的位图 向量图形 概述 安卓运行各种各样的设备&#xff0c;它们有不同的屏幕大小和屏幕的像素深度。 系统执行基本的缩放和变形来适配在不同的屏幕…...