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

SpringBoot解决下载接口文件名中文乱码问题的3种方法

问题场景

       在Spring或SpringBoot开发的项目中,下载文件接口经常会出现在下载文件时,文件名为中文或者包含中文时,可能会出现乱码的问题。

问题分析

一、页面与服务器编码不一致

       文件名乱码问题,常见原因是编码不一致。即服务器使用的编码方式与客户端(即Java程序)使用的编码方式不一样时,就会出现中文字符乱码。如果Java程序使用的是默认的ISO-8859-1编码方式,而服务器使用的是UTF-8编码方式,那么下载的文件名就会出现乱码现象。

二、Content-Disposition头部信息问题

          如果开发的服务接口没有正确设置Content-Disposition头部信息,浏览器将无法正确解析文件名,就会导致下载的文件名乱码 ,特别是文件名为中文或者包含中文时。其中Content-Disposition头部信息就是用于告诉浏览器如何处理下载的文件。

解决方法

方式一:设置合适的编码方式

解决编码不一致问题的方法是将Java程序的编码方式设置为与服务器一致的方式。我们可以对文件名称使用 URL编码方式进行处理 。

    String fileName = "测试下载文件.doc";//解决下载文件时文件名乱码问题byte[] fileNameBytes = fileName.getBytes(StandardCharsets.UTF_8);fileName = new String(fileNameBytes, 0, fileNameBytes.length, 
StandardCharsets.ISO_8859_1);long contentLength = file.length();HttpHeaders httpHeaders = new HttpHeaders();httpHeaders.setContentType(MediaType.valueOf(contentType));httpHeaders.setContentDispositionFormData("attachment", fileName);httpHeaders.setContentLength(contentLength);

方式二:设置正确的Content-Disposition头部信息

        针对解决缺少Content-Disposition头部信息的情况,合适的方法是在服务器端设置正确的头部信息。使用setContentType方法设置了Content-Type为application/octet-stream,表示下载的是二进制文件。然后,我们使用setHeader方法设置了Content-Disposition头部信息,其中filename参数指定了下载的文件名。

String fileName = "下载文件.doc";
response.setContentType("application/octet-stream");	
response.setHeader("Content-Disposition","attachment; filename=\"" + fileName + "\"");	

方式三:同时解决编码和头部信息问题

文件名称使用URL编码处理,对于文件名种有空格, 就会被截断的情况。不能直接把空格替换成%20, 因为%会被url编码转成%25。建议的方式是先使用URL编码, 再使用+号进行替换。

public void download(HttpServletResponse response){String fileName = "下载文件";// 文件名先进行url编码, 避免乱码问题// 把+用%20进行替换fileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");response.setContentType("application/octet-stream");// 注意是 filename*=utf-8''response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".doc");}

重点关注参数:attachment;filename*=utf-8''

http://www.xdnf.cn/news/1004635.html

相关文章:

  • Bash (Bourne Again SHell)
  • Ftrace 调试 Rockchip MIPI D-PHY 驱动步骤
  • 明远智睿SD2351核心板:边缘计算时代的工业级核心引擎深度解析
  • 深度学习之模型压缩三驾马车:基于ResNet18的模型剪枝实战(3)
  • DEVICENET转MODBUS TCP网关连接DeviceNet数字远程IO模块配置案例
  • 解决新版RN 热更新报错:recreateReactContextInBackground
  • Unity Mecanim C# 动画切换实践:实现随机播放待机动画
  • 网络安全:OWASP防护守则
  • Tomcat调优
  • Ntfs!NtfsAllocateRestartTableIndex函数分析和Ntfs!DIRTY_PAGE_ENTRY_V0结构的关系
  • CSS 基础选择器 文字控制属性 综合案例
  • python3.12安装记录
  • 分割任意组织:用于医学图像分割的单样本参考引导免训练自动点提示方法|文献速递-深度学习医疗AI最新文献
  • MCU、MPU、GPU、Soc、DSP、FPGA、CPLD……它们到底是什么?
  • 日本云服务器租用多少钱合适
  • 当卷积作用于信号处理
  • AppInventor2原生进度条组件LinearProgress用法及注意点
  • 第四讲 基础运算之小数运算
  • SAP ERS 自动化发票
  • ubuntu 挂载问题
  • COHERENT XPRV23光电接收器控制软件
  • 观点 | 技术型企业在参数堆砌下的品牌识别度缺失
  • 5分钟玩转Swagger UI:Docker部署+静态化实战
  • 零基础设计模式——行为型模式 - 观察者模式
  • 将创世SD NAND FLASH设计在无人机上,可从硬件适配、接口与协议兼容、性能匹配
  • 不同环境的配置文件
  • OpenCV 图像几何形状绘制
  • 回归-嵌入式与c概念
  • docker 单机部署redis集群(一)
  • 股指期货入门基础知识