文件上传踩坑=_= MultiPartFile

发布于:2023-01-22 ⋅ 阅读:(1044) ⋅ 点赞:(0)

概述:上传文件时,后端获取文件名,采取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);

产生原因:根据多方资料查看,可能排查出的原因,是因为编码的格式所导致,解决方案啊也是采用编码的方式进行,具体原因有待考察。    

MultipartFile原理:

一:使用方式/特点

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进行解码操作,解决问题。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到