xlsx文件下载异常问题

前端调用我的后端接口下载xlsx文件,里面的数据没有正常展示。如下所示:

查看前端响应头里面。多了个charset=utf-8;

java 复制代码
application/octet-stream;charset=utf-8

如果是下面这种响应不会有问题,但是上面二进制流有charset=utf-8,浏览器会把这个当文本处理,不会解析成文件。

改动之前下载接口如下:

java 复制代码
  @ApiOperation(value = "oss文件下载")
    @GetMapping("downOssFile")
    public ResponseEntity<byte[]> getFileByUrl(String url, String fileName) {
        byte[] body = ossManager.download(url);
        HttpHeaders headers = new HttpHeaders();

        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        try {
            String encodeFileName = URLEncoder.encode(fileName, "utf-8").replaceAll("\\+", "%20");
            headers.set("Content-Disposition", "attachment;filename=" + encodeFileName);
        } catch (UnsupportedEncodingException e) {
            log.error("oss文件下载失败,e:", e);
            throw new RuntimeException(e);
        }
        ResponseEntity<byte[]> result = ResponseEntity.ok().headers(headers).body(body);
        return result;
    }

这个接口返回体是使用Spring的ResponseEntity<byte[]> , Spring 的 ByteArrayHttpMessageConverter 会序列化处理该响应体。 最后过滤器在 response 提交后仍可修改 header。

检查我的web.xml文件配置是这样的,强制在所有接口的请求的响应头里面加上charset=UTF-8设置。这是问题的根源所在。

java 复制代码
    <filter>
		<filter-name>ProjectEncoding</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<async-supported>true</async-supported>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>ProjectEncoding</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

下面是我修改之后的下载接口:

java 复制代码
@ApiOperation(value = "oss文件下载")
    @GetMapping("downOssFile")
    public void getFileByUrl(String url, String fileName, HttpServletResponse response) throws IOException {
        byte[] body = ossManager.download(url);
        response.setHeader("Content-Type", "application/octet-stream");
        String encodeFileName = URLEncoder.encode(fileName, "utf-8").replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment;filename=" + encodeFileName);
        response.getOutputStream().write(body);
    }

使用原生的Response方法,绕过过滤器,getOutputStream().write() 会提前提交 response,过滤器无法再改charset。这样xlsx文件才能正常解析。

这个问题确实也排查了好久,总结来说对于上传以及下载文件异常问题首先考虑的就是响应头或者请求头,一般问题都出在这两个。

相关推荐
hhhhhaaa几秒前
Java 并发编程核心原理与生产级最佳实践
java·后端
qwert10373 分钟前
深入解析Python标识符:定义、规则、规范与实践指南
开发语言·数据库·python
cqwuliu9 分钟前
Freemarker模板工具
java·开发语言
学习,学习,在学习10 分钟前
Qt多线程的使用与注意事项
开发语言·数据库·qt
asdfg125896311 分钟前
`(line1, line2) -> line1 + line2` 此Lambda 表达式的理解
java·开发语言
如竟没有火炬13 分钟前
去除重复字母——贪心+单调栈
开发语言·数据结构·python·算法·leetcode·深度优先
AI人工智能+电脑小能手21 分钟前
【大白话说Java面试题 第49题】【JVM篇】第9题:什么是双亲委派机制?介绍一下运作过程。?
java·开发语言·jvm
码农-阿杰24 分钟前
Java 线程中断机制深度解析:从 API 到底层 C++ 实现
java·开发语言·c++
Brilliantwxx26 分钟前
【C++】priority_queue以及 仿函数 的学习
开发语言·c++·笔记·学习·算法
风味蘑菇干26 分钟前
斗地主案例
java·数据结构·算法