一、该问题的重现步骤是什么?
1. 增加了附件二进制方式
2.
3.
二、你期待的结果是什么?实际看到的又是什么?
为了适配附件分片上传,附件上传增加二进制流的方式,测试发现txt文本上传可以正常打开,jpg文件上传无法正常打开,原始jpg文件是101kb,上传完成之后变成143kb。
三、你正在使用的是什么产品,什么版本?在什么操作系统上?
Bladex联合版, 4.5.0.RELEASE,Linxu系统
四、请提供详细的错误堆栈信息,这很重要。
原始文件:
上传合并成功之后的文件
五、若有更多详细信息,请在下面提供。
/**
* 分片信息校验之后开始分片上传文件,接受二进制流
* <p>专用</p>
* @return
*/
@PostMapping(
value="/uploadChunkOctetStream",
consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE
)
public R<FileChunkCheckResponse> uploadChunkOctetStream(HttpServletRequest request, @Parameter(description = "文件的唯一标识", required = true) @RequestParam String identifier,
@Parameter(description = "分块的序号,从0开始", required = true) @RequestParam Integer index,
@Parameter(description = "分块大小,最后一块可能小于该值", required = true) @RequestParam Long chunkSize,
@Parameter(description = "文件名,传入的文件名", required = true) @RequestParam String fileName,
@Parameter(description = "分块的总数量,依据chunkSize计算", required = true) @RequestParam Integer totalChunks,
@Parameter(description = "文件总大小", required = true) @RequestParam Long totalSize) throws IOException{
FileChunkRequest fileChunkRequest = FileChunkRequest.builder()
.identifier(identifier)
.chunkNumber(index+1)
.chunkSize(chunkSize)
.filename(fileName)
.totalChunks(totalChunks)
.currentChunkSize(chunkSize)
.totalSize(totalSize)
.build();
FileChunkCheckResponse upload = chunkService.upload(fileChunkRequest,request.getInputStream());
return R.data(upload);
}
public FileChunkCheckResponse upload(FileChunkRequest fileChunkRequest, InputStream inputStream) {
String identifier = fileChunkRequest.getIdentifier();
String path = chunkFileProperties.getChunkPath() + File.separator + identifier;
// 校验 chunkNumber 合法性
int chunkNumber = fileChunkRequest.getChunkNumber();
int totalChunks = fileChunkRequest.getTotalChunks();
if (chunkNumber < 0 || chunkNumber > totalChunks) {
throw new IllegalArgumentException("Invalid chunk number: " + chunkNumber);
}
boolean exist = FileUtil.exist(path);
if (!exist) {
// 创建文件夹
FileUtil.mkdir(path);
}
String chunkFilePath = path + File.separator + chunkNumber;
File chunkFile = new File(chunkFilePath);
try (OutputStream outputStream = new FileOutputStream(chunkFilePath)) {
byte[] buffer = new byte[8192];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
// 保存分片信息
Chunk chunk = getChunk(fileChunkRequest.getIdentifier(), fileChunkRequest.getChunkNumber());
if (Func.isEmpty(chunk)) {
chunk = new Chunk();
}
chunk.setChunkNumber(fileChunkRequest.getChunkNumber());
chunk.setChunkSize(fileChunkRequest.getChunkSize());
chunk.setCurrentChunkSize(fileChunkRequest.getCurrentChunkSize());
chunk.setFilename(fileChunkRequest.getFilename());
chunk.setIdentifier(fileChunkRequest.getIdentifier());
chunk.setRelativePath(path);
chunk.setTotalChunks(fileChunkRequest.getTotalChunks());
chunk.setTotalSize(fileChunkRequest.getTotalSize());
baseMapper.insertOrUpdate(chunk);
// 查询所有分块
List<Chunk> chunkList = this.getChunkList(fileChunkRequest.getIdentifier());
List<Integer> chunkNumberList = chunkList.stream().mapToInt(Chunk::getChunkNumber).boxed().toList();
FileChunkCheckResponse response = FileChunkCheckResponse.builder().uploaded(chunkNumberList).build();
// 是否上传完成
if (chunkNumberList.size() == totalChunks) {
response.setNeedMerge(Boolean.TRUE);
}
// 是否需要添加当前分块
return response;
}catch (IOException e) {
log.error("Failed to write chunk file: {}", chunkFilePath, e);
throw new ServiceException("Failed to write chunk file: " + chunkFilePath);
}
}
你用一个原生的springboot工程测试下你的这套代码是否能正常上传成功
使用SpringBoot写了个demo程序,是可以的
demo程序也需要实现oss上传才可以,如果demo程序能正常分片上传到oss,并且能正常加载,但是bladex里同样的逻辑不行,则把你的完整demo发到我们邮件:bladejava@qq.com
demo中的代码原封不动拿到bladex框架里面,上传的附件就有问题,现在怀疑是框架层做了什么处理影响了?
demo已发到你们邮箱,不需要上传到oss这一步就出问题了,写入到本地临时文件,文件就比实际要大
框架里会对request做一次缓存方便流随时获取,逻辑在这里:https://center.javablade.com/blade/BladeX-Tool/src/branch/master/blade-core-boot/src/main/java/org/springblade/core/boot/request/BladeRequestFilter.java
你可以通过配置文件,配置特定的接口进行跳过包装:https://center.javablade.com/blade/BladeX-Tool/src/branch/master/blade-core-boot/src/main/java/org/springblade/core/boot/request/RequestProperties.java#L51
配置试试看
可以了