Java Spring Boot:WebClient内存下载XLS及对象转换问题
使用Spring WebFlux WebClient内存下载并读取XLS文件
问题分析
你之前遇到的UnsupportedMediaTypeException,核心原因有两个:
- 错误设置了请求头
Content-Type:这个头用于标识请求体的类型,而GET请求无需设置;你应该通过accept方法告知WebClient可接受的响应类型。 - 服务器返回的Content-Type存在不一致(错误提示为
text/xml,但Postman显示是application/vnd.ms-excel),需要让WebClient忽略这种不匹配,强制处理响应体。
解决方案
方法1:直接获取字节数组(与RestTemplate逻辑一致)
直接将响应体转换为byte[],这是WebClient原生支持的类型,无需额外配置:
byte[] fileBytes = webClientBuilder.build().get() .uri(xlsLink) .accept(MediaType.parseMediaType("application/vnd.ms-excel")) // 指定接受的响应类型 .retrieve() .bodyToMono(byte[].class) .block(); // 非阻塞场景可改用subscribe,此处用block实现同步获取结果
方法2:使用ByteArrayResource
如果需要用ByteArrayResource,可通过exchangeToMono手动处理响应体:
ByteArrayResource xlsResource = webClientBuilder.build().get() .uri(xlsLink) .accept(MediaType.parseMediaType("application/vnd.ms-excel")) .exchangeToMono(response -> { // 读取响应体为字节数组后包装成ByteArrayResource return response.bodyToMono(byte[].class) .map(bytes -> new ByteArrayResource(bytes)); }) .block();
内存中读取XLS内容示例(基于Apache POI)
拿到字节数组后,可使用Apache POI在内存中解析XLS,无需保存到磁盘:
<!-- Maven依赖 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.5</version> </dependency>
解析代码:
try (InputStream inputStream = new ByteArrayInputStream(fileBytes); HSSFWorkbook workbook = new HSSFWorkbook(inputStream)) { // 获取第一个工作表 HSSFSheet sheet = workbook.getSheetAt(0); // 遍历行与单元格,打印内容 for (Row row : sheet) { for (Cell cell : row) { String cellValue; switch (cell.getCellType()) { case STRING: cellValue = cell.getStringCellValue(); break; case NUMERIC: cellValue = DateUtil.isCellDateFormatted(cell) ? cell.getDateCellValue().toString() : String.valueOf(cell.getNumericCellValue()); break; case BOOLEAN: cellValue = String.valueOf(cell.getBooleanCellValue()); break; default: cellValue = ""; } System.out.print(cellValue + "\t"); } System.out.println(); } } catch (IOException e) { e.printStackTrace(); }
关键注意点
- 不要设置多余请求头:GET请求无需
Content-Type和Content-Disposition请求头,这些属于响应头范畴。 - 非阻塞场景优先用
subscribe:在WebFlux的非阻塞环境中,尽量避免调用block(),改用响应式方式处理结果。
内容的提问来源于stack exchange,提问作者Allteran
相关产品推荐
相关产品推荐

