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

news2025/1/8 21:09:05

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
{

    @Bean
    public 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 {
        @Override
        public 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项目出现中文乱码的问题的解决思路及过程,对比了网上说明的解决方法,发现也基本上涵盖了大多数情况,大家可以参考

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

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

相关文章

##07 从线性回归到神经网络:PyTorch实战解析

文章目录 前言线性回归基础理论背景实现步骤神经网络介绍理论背景实现步骤从线性回归到神经网络结论前言 在深度学习的浩瀚宇宙中,线性回归和神经网络是两个基本但极其重要的概念。线性回归模型是统计学和机器学习的基石之一,而神经网络则是深度学习技术的核心。本文旨在通过…

【日志革新】在ThinkPHP5中实现高效TraceId集成,打造可靠的日志追踪系统

问题背景 最近接手了一个骨灰级的项目&#xff0c;然而在项目中遇到了一个普遍的挑战&#xff1a;由于公司采用 ELK&#xff08;Elasticsearch、Logstash、Kibana&#xff09;作为日志收集和分析工具&#xff0c;追踪生产问题成为了一大难题。尽管 ELK 提供了强大的日志分析功…

在时间同步应用上节省大量时间!德思特GNSS模拟器是怎么做到的?

​ 作者介绍 德思特Safran GNSS模拟器是一款综合解决方案&#xff0c;专为精确的PNT&#xff08;位置、导航和时间&#xff09;仿真与测试设计。它超越了传统GNSS定位导航仿真&#xff0c;也能提供极高的授时精度。 这款模拟器对于评估和提升GNSS接收机及同步系统的整体性能至…

前端JS必用工具【js-tool-big-box】,验证是否是Unicode字符,获取一个字符串的字节长度,以及新增发送JSONP跨域请求的方法

js-tool-big-box&#xff0c;目前已经收集到了用户需求&#xff0c;希望可以添加一些公用方法&#xff0c;我觉得这很好&#xff0c;我们一起把这个前端通用工具做大一些&#xff0c;帮助更多的小伙伴少些util代码&#xff0c;更多的关注于自己的业务开发&#xff0c;真是不错。…

OpenCV与AI深度学习 | 如何使用YOLOv9检测图片和视频中的目标

本文来源公众号“OpenCV与AI深度学习”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;如何使用YOLOv9检测图片和视频中的目标 1 介绍 在之前的文章中&#xff0c;我们探索了使用 YOLOv8 进行对象检测。现在&#xff0c;我们很高兴…

【仪酷LabVIEW AI工具包案例】使用LabVIEW AI工具包+YOLOv5结合Dobot机械臂实现智能垃圾分类

‍‍&#x1f3e1;博客主页&#xff1a; virobotics(仪酷智能)&#xff1a;LabVIEW深度学习、人工智能博主 &#x1f384;所属专栏&#xff1a;『仪酷LabVIEW AI工具包案例』 &#x1f4d1;上期文章&#xff1a;『【YOLOv9】实战二&#xff1a;手把手教你使用TensorRT实现YOLOv…

Spring - 7 ( 13000 字 Spring 入门级教程 )

一&#xff1a;Spring Boot 日志 1.1 日志概述 日志对我们来说并不陌生&#xff0c;我们可以通过打印日志来发现和定位问题, 或者根据日志来分析程序的运行过程&#xff0c;但随着项目的复杂度提升, 我们对日志的打印也有了更高的需求, 而不仅仅是定位排查问题 比如有时需要…

关于 c++ 中字符串 string 及 常量字符串的换行与使用

&#xff08;1&#xff09;例如 cout << " ddddddddddddddddddd" 。当输出字符太长&#xff0c;就需要换行。疑问是如何写代码&#xff0c;才可以保证源代码中的字符串换行被正确编译呢&#xff1f;测试一下&#xff0c;如下图可见&#xff0c;如此换行&#x…

STM32:GPIO输入输出

文章目录 1、GPIO介绍1.1 GPIO的基本结构1.1 GPIO的位结构 2、 GPIO工作模式3、GPIO标准外设库接口函数3.1 RCC接口函数3.2 GPIO接口函数3.2.1 GPIO的读取函数3.2.1 GPIO的写入函数 4、GPIO的初始化 1、GPIO介绍 GPIO&#xff08;General Purpose Input Output&#xff09;通用…

【MQTT】服务端、客户端工具使用记录

目录 一、服务端 1.1 下载 1.2 相关命令 &#xff08;1&#xff09;启动 &#xff08;2&#xff09;关闭 &#xff08;3&#xff09;修改用户名和密码 1.3 后台管理 &#xff08;1&#xff09;MQTT配置 &#xff08;2&#xff09;集群概览 &#xff08;3&#xff09;…

场外期权个股怎么对冲?

今天期权懂带你了解场外期权个股怎么对冲&#xff1f;场外个股期权是一种在非交易所市场进行的期权交易&#xff0c;它允许投资者针对特定的股票获得未来买入或卖出的权利。 场外期权个股怎么对冲&#xff1f; 持有相反方向的期权&#xff1a;这是最直接的对冲方法&#xff0c…

今晚 19:00 | 从这两个问题入手,带你了解数据要素相关税务问题

五一假期已经结束&#xff0c;返工后当然是继续劳动啦~数据要素系列直播《星光对话》第三期也将在今晚19:00&#xff0c;继续跟大家见面。 本期直播&#xff0c;依然由 星光数智咨询总监 刘靖 主讲&#xff0c;带来&#xff1a;《数据要素相关税务问题解读》。 主要围绕两个问题…

怎么快速分享视频文件?用二维码看视频的方法

怎样不通过传输下载分享视频内容呢&#xff1f;以前分享视频内容&#xff0c;大多会通过微信、QQ、邮箱、网盘等形式来传递。但是这种方式需要下载后才可以观看&#xff0c;不仅占用手机内存&#xff0c;而且效率也比较低&#xff0c;所以现在很多人会采用视频生成二维码的方式…

为 Flutter 应用设置主题:ThemeData 和 ColorScheme 指南

在媒体和其他来源中有许多关于这个主题的文章&#xff0c;那么这篇文章的必要性是什么&#xff1f; 在本文中&#xff0c;我计划仅关注 ThemeData 小部件的关键点以及我的开发经验中最常用的参数&#xff0c;并且您将获得有关每个参数如何对您的应用程序执行操作的简要说明。 …

LeetCode70:爬楼梯

题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 解题思想 1.确定dp数组以及下标的含义 dp[i]&#xff1a; 爬到第i层楼梯&#xff0c;有dp[i]种方法 2.确定递推公式 从dp[i]的定义可以…

旋转测径仪的常见故障和排除方法

关键字: 旋转测径仪,测径仪常见故障,测径仪故障排除方法,测径仪维护,测径仪较零 点击 “开始测量”按钮时提示“初始化失败&#xff01;”无法进行测量。 ◆ 检查控制柜面板“工作”指示灯&#xff08;绿&#xff09;是否点亮&#xff1b; ◆ 最小化软件窗口&#xff0c;查看…

解密某游戏的数据加密

前言 最近有个兄弟通过我的视频号加我&#xff0c;咨询能否将这个dubo游戏游戏开始前就将数据拿到从而进行押注&#xff0c;于是通过抓包工具测试了下&#xff0c;发现数据有时候是明文&#xff0c;有时候确实密文&#xff0c;大致看了下有这几种加密&#xff1a;Md5aes、Md5&a…

用Pycharm对图片中表格进行文字识别,并导出到xlsx文件中

需要使用到百度API对图片文字进行识别 在百度智能云官网中注册一个账号百度智能云-登录https://login.bce.baidu.com/ 之后在管理中心里创建应用 创建完成后会得到&#xff1a; 记下一下AppID&API Key&Secret Key这三个值&#xff0c;调用接口时使用。 示例图片&…

字符编码(十六进制)

题目描述 假设一个简易的变长编码规则XUTF:每个字符有一个唯一编号值 unicodeVal(如汉字“华”的编号十进制值是21326),使用1~6个字节进行编码,编码规则如下: 编码格式: 编号值范围编码后字节长度n二进制格式(x 表示有效位,其它为固定位)[0, 2^7)1字节1xxxxxxx[2^7,…

数智算网,链启未来 | 算力网络子链诚邀各方加入

4月28日&#xff0c;在中国移动算力网络大会期间&#xff0c;由中国移动集团主办&#xff0c;中国移动研究院和云能力中心联合承办的“数智算网&#xff0c;链启未来”共链行动算力网络专场会议成功召开。中国移动研究院副院长段晓东&#xff0c;中国移动集团首席专家、云能力中…