Spring Boot MultipartFile 上传 getOriginalFileName 因浏览器而异

Posted

技术标签:

【中文标题】Spring Boot MultipartFile 上传 getOriginalFileName 因浏览器而异【英文标题】:Spring Boot MultipartFile upload getOriginalFileName different depending on browser 【发布时间】:2018-04-10 02:09:08 【问题描述】:

我使用的是spring boot 1.5.7-RELEASE版本,我正在使用以下方法上传文件:

@Autowired private MyService mySerice;

@RequestMapping(value = "/uploadFile", method =  RequestMethod.POST , produces =  MediaType.MULTIPART_FORM_DATA_VALUE,
     MediaType.APPLICATION_FORM_URLENCODED_VALUE, MediaType.APPLICATION_JSON_VALUE )
public void upload(@RequestParam("file") MultipartFile uis, @RequestParam("user_id") String userId) 
    MyFile myFile = new MyFile();
    if (!uis.isEmpty()) 
        myFile.setFile(uis.getBytes());
        myFile.setName(uis.getOriginalFilename());
        myFile.setUserId(userId);
        myService.upload(myFile); 
    

我正在尝试将此文件上传到 mysql 中的此表:

CREATE TABLE `file_user` (
`id` int(5) UNSIGNED NOT NULL,
`user_id` bigint(20) UNSIGNED NOT NULL,
`file` mediumblob NOT NULL,
`name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
ALTER TABLE `file_user` ADD PRIMARY KEY (`id`);

前端是带有 Ajax 的简单表单 html

var fileInput = $("#file_form_post")[0].files[0];
var data = new FormData();
data.append("file", fileInput);
data.append("user_id", $("#txt_uid").val());
$.ajax(
    url: 'mypage.com:9002/uploadFile',
    type: 'POST',
    data: data,
    cache: false,
    contentType: false,
    processData: false,
    headers: Accept: "application/json",
    success: function (r) 
                alert('Upload OK');
            ,
    error: function (request, status, error) 
                alert('Upload error');
            
    ); 

当我从 Internet Explorer 或 Microsoft Edge 上传文件时,uis.getOriginalFilename() 方法会返回完整路径。

例如:c:\users\daniel\myfile.txt

如果我从 Google Chrome 上传文件,uis.getOriginalFileName() 的值只是文件名。

例如:myfile.txt

我怎样才能只获得每个浏览器的名称而没有路径?

是否缺少一些 @Bean 来获得它?

谢谢。

【问题讨论】:

只是不要相信浏览器给出的文件名。相反,您可以在保存文件时设置自定义名称。 【参考方案1】:

使用 apache commons IO。它处理 Unix 或 Windows 格式的文件。

org.apache.commons.io.FilenameUtils.getName(multipartFile.getOriginalFilename());

【讨论】:

【参考方案2】:

javaLover 的建议并不是一个好方法,因为它依赖于平台。例如,如果您的应用程序在 Linux 上运行并且您从 Windows 上传文件,Path.getFileName() 将无法识别 Windows 用作名称分隔符的反斜杠,并且您将再次获得完整路径而不仅仅是文件名。这就是为什么最好手动完成,比如

String fileName = uis.getOriginalFilename();
int startIndex = fileName.replaceAll("\\\\", "/").lastIndexOf("/");
fileName = fileName.substring(startIndex + 1);
myFile.setName(fileName);

这里我们首先将反斜杠替换为正斜杠,只关心一种风格的分隔符,然后找到最后一个分隔符在哪里。接下来,我们从找到的索引中删除字符串加上一,以摆脱斜线本身。即使getOriginalFilename() 只返回没有路径的文件名,这段代码也可以工作,因为startIndex 将是-1,而生成的substring(0) 调用不会有任何效果。

【讨论】:

【参考方案3】:

以这种方式修改 Java 代码中的以下行:

myFile.setName(java.nio.file.Paths.get(uis.getOriginalFilename()).getFileName());`

【讨论】:

以上是关于Spring Boot MultipartFile 上传 getOriginalFileName 因浏览器而异的主要内容,如果未能解决你的问题,请参考以下文章

spring boot MultipartFile[]文件上传

Spring boot - 如何在 rest 应用程序中验证 Multipartfile

spring-boot上传文件MultiPartFile获取不到文件问题解决

当我在 Spring Boot 应用程序中使用 CommonsMultipartResolver 时,MultipartFile 为空

如何使用邮递员和 Spring Boot 发送 multipartFile 和 Json

Spring Boot MultipartFile 上传 getOriginalFileName 因浏览器而异