赞
踩
概述:上传文件时,后端获取文件名,采取MulipartFile file 作为文件的类型,通过file.getOriginalFileName,产生中文乱码,导致下载文件,文件可能打不开的情况。
结论:我的解决方案是修改编码获取文件名的方式。
- @ApiOperation(value = "文件上传", notes = "文件上传")
- @PostMapping(value = "/upload")
- public ResponseEntity<String> upload(@ApiParam(value = "待上传的文件", required = true) @RequestParam(value = "file") List<MultipartFile> files) {
- String result;
- HttpStatus status = HttpStatus.OK;
- try {
- List<NoticeAttachmentDTO> noticeAttachments = new ArrayList<>();
- for (MultipartFile file : files) {
- String fileName = new String(file.getOriginalFilename().getBytes("ISO-8859-1"),"UTF-8");
- logger.debug("文件上传 file:{}", fileName);
- NoticeAttachmentDTO noticeAttachment = new NoticeAttachmentDTO();
- try {
- String gatewayExternal = tenantUtils.getGatewayExternal(SessionHolder.getUser().getTenantCode());
- String key = cloudFactory.getCloud().uploadFile(file, fileName);
- noticeAttachment.setId(key);
- String fileSize = new BigDecimal(file.getSize()).divide(new BigDecimal(1024), 2, BigDecimal.ROUND_UP) + "KB";
- noticeAttachment.setFileSize(fileSize);
- String path = gatewayExternal.concat("/notice/api/v1/noticeCenter/noticeDetail/v1/getUrl/").concat(key);
- noticeAttachment.setUrl(path);
- String posterPath = "";
- if (FileHeaderUtils.judgeVedio(fileName)) {
- String posterkey = key;
- if (!CloudFactory.cloudSwitch.equals(Constant.ALIYUN)) {
- posterkey = toolVideoUtils.getScreenshot(file);
- }
- if (org.apache.commons.lang3.StringUtils.isNotBlank(key)) {
- posterPath = gatewayExternal.concat("/notice/api/v1/noticeCenter/noticeDetail/v1/getUrl/poster/").concat(posterkey);
- }
- }
- noticeAttachment.setPoster(posterPath);
- } catch (Exception e) {
- noticeAttachment.setIsSuccess("N");
- noticeAttachment.setErrMessage(Throwables.getStackTraceAsString(e));
- } finally {
- noticeAttachment.setFileName(fileName);
- noticeAttachments.add(noticeAttachment);
- }
- }
- result = ResponseTO.successResponse(noticeAttachments);
- } catch (Exception e) {
- logger.error("OSS上传文件异常", e);
- result = ResponseTO.errorResponse(e);
- }
- return new ResponseEntity<>(result, status);
- }
- String fileName = new String(file.getOriginalFilename().getBytes("ISO-8859-1"),"UTF-8");
- logger.debug("文件上传 file:{}", fileName);
产生原因:根据多方资料查看,可能排查出的原因,是因为编码的格式所导致,解决方案啊也是采用编码的方式进行,具体原因有待考察。
一:使用方式/特点
1.它可以接收使用多种请求方式来进行上传文件的代表形式。表单的形式提交。
2.文件内容可以存储到内存或者永久存在磁盘临时位置。
3.无论何种情况,用户可以自由拷贝文件内容到session存储中,或者以一种永久存储的形式存储。
4.临时性存储会在请求结束后清理。
二:常用方法
它是一个接口,继承于InputStreamSource,并且封装了getInputStream方法,返回InputStream类型,这是它能转换为输入流的原因。
multipartFile.getInputStream();
(1) getName方法
getName获取的是前后端约定的传入文件的参数的名称,SpringBoot中采用@Param("uploadFile")注释定义。
(2) getOriginalFileName方法
getOriginalFileName方法获取的是文件的完整名称,包括文件名称+文件拓展名。
(3) getContentType方法
getContentType方法获取文件类型,是文件类型,不是扩展名
(4) isEmpty方法
isEmpty方法用来判断传入文件是否为空,如果空则表示没有传入任何文件。
(5) getSize方法
getSize方法获取文件的大小,单位是字节
(6) getBytes方法
getBytes方法将文件转换成一种字节数组方式进行传输,抛出IO异常
(7) getInputStream方法
getInputStream方法用来将文件转换为输入流形式传输,抛出IO异常
(8) transferTo方法
transferTo方法就用来将接收文件传输到给定目标路径,会抛出IO、iIllegalStateException异常,实际使用较少(但是项目代码用了)
这里有一点,是return返回的name不是null或者空,如果使用MultipartFile接收文件,name@Param("uploadFile")定义的接收文件的名称规则是必不可少的,这样才能接收文件,没有定义则接收不到文件。
1.从部分问题探究的方案来看,提到的MultipartFile fileName 是调用HttpClient上传文件,他们提到了需要设置http为兼容模式,否则会使用mime默认的编码(US-ASCII),其中有一部分关于MultipartEntityBuilder的内容(原谅我没看过),待补充。
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setCharset(Charset.forName("UTF-8"));
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//设置浏览器兼容模式,否则后台接口接收到的文件名中文乱码?????.xlsx
最终解决问题发现 原因在于 [] 这两个特殊字符 作为key时候没有进行编码,导致上传出问题。将这个取得的key进行解码操作,解决问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。