uploadifive + MissingServletRequestPartException: Required request part 'file_upload' is not present

最近学习SpringBoot时,使用jquery uploadify/uploadifive 插件进行图片上传时碰到一坑,在此记录下。解决方案看最后。

 

问题描述:页面使用普通form提交方式后台可以正确无误获得到图片,但是使用uploadify组件时则总是抛出异常:

Resolved exception caused by Handler execution: org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file_upload' is not present

使用Form可以正常提交和返回的图片页面:

 

<!DOCTYPE HTML>
<html>
<head>
    <title>Image Upload</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<form method="POST" action="/upload" enctype="multipart/form-data">
    <table>
        <tr>
            <td><label path="file_upload">Select a file to upload</label></td>
            <td><input type="file" name="file_upload" id="upload_file"/></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit"/></td>
        </tr>
    </table>
</form>

</body>
</html>

后台响应的Spring代码:

 

package com.my.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Description: To do
 * <p>
 * Author : Adore Chen
 * Created: 2018-08-23
 */
@Controller
public class FileUploadController {

    private Logger logger = LoggerFactory.getLogger(getClass());

    // save uploaded file to this folder
    private String uploadDir = System.getProperty("user.home") + "/upload/";

    public FileUploadController(){
        File dir = new File(uploadDir);
        if(!dir.exists()){
            dir.mkdirs();
        }
    }

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public String upload(@RequestParam("file_upload") MultipartFile file, ModelMap modelMap) {
        modelMap.addAttribute("image", file);

        // Save file on system
        if (!file.isEmpty()) {
            try{
                Path path = Paths.get(uploadDir + file.getOriginalFilename());
                Files.write(path, file.getBytes());
                logger.info("write file to: {}", path);
            }catch (Exception e){
                logger.error("upload file error", e);
            }
        }

        return "searchResult";
    }

} 

 

Application代码如下:

package com.my.controller;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import javax.servlet.MultipartConfigElement;

/**
 * Description: To do
 * <p>
 * Author : Adore Chen
 * Created: 2018-08-23
 */
@SpringBootApplication
public class Application {

    private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024;

    public static void main(String[] args){
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext applicationContext){
       return args -> {
            System.out.println("Picture Search Application Started ... ===>");
        };
    }

    @Bean
    MultipartConfigElement multipartConfigElement() {
        return new MultipartConfigElement(System.getProperty("java.io.tmpdir"),
                MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2);
    }

    @Bean
    public StandardServletMultipartResolver multipartResolver() {
        return new StandardServletMultipartResolver();
    }

}

页面使用form按钮太多,不方便布局,于是准备使用js框架上传文件。jquery.file_upload组件功能强大,但是文档和使用太复杂,不想读他们大片大片的文档,于是选择了简洁的jquery uploadify框架。

 

uploadify flash版,免费版,现在很多主流浏览器firefox/safri都不支持flash了,chrome默认也是关闭的。

uploadifive html5版,支持主流浏览器,收费版;(推荐使用,给他们打个广告)。

 

使用uploadifive文件上传的页面:[官方文档demo版-稍微修改]

<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>UploadiFive Test</title>
    <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
    <script src="uploadifive/jquery.uploadifive.js" type="text/javascript"></script>
    <link rel="stylesheet" type="text/css" href="uploadifive/uploadifive.css">
    <style type="text/css">
        body {
            font: 13px Arial, Helvetica, Sans-serif;
        }
    </style>
</head>

<body>
<h1>Uploadify Demo</h1>
<form>
    <div id="queue"></div>
    <input id="file_upload" type="file" name="file_upload" />
</form>

<script type="text/javascript">
    $(function() {
        $('#file_upload').uploadifive({
            'uploadScript' : '/upload'
            // Put your options here
        });
    });
</script>
</body>
</html>

 然后上传到后端就抛出异常:

MissingServletRequestPartException: Required request part 'file_upload' is not present

想了很久都没有找到原因, 经过前面form页面可以正确上传排除了后端代码有问题的可能,那么确实是后端抛出的异常,第一个反应就是input标签的name没有设置对,检查了发现没有任何问题,就是file_upload,有点蒙了。

 

最后怀疑uploadifive组件可能提交数据格式有问题,于是把chrome develop tool调出来发现看不了request的数据(问了度娘未果,后来发现要点击filter选择all就有了),真是坑啊。还是使用firefox吧,这个好用。

分析提交到后的数据如下:

------WebKitFormBoundaryp8SORXOshiJc12is Content-Disposition: form-data; name="Filedata"; filename="WechatIMG38.jpeg" Content-Type: image/jpeg ------WebKitFormBoundaryp8SORXOshiJc12is--

看到name=“Filedata”这项顿时明白为什么了,明明我的input name=file_upload, uploadifive却把他写成Filedata不报错才怪。

以前uploadify早期版本挺好用的啊,没有这个坑的,新收费的版本居然还有这么一坑。它给的demo文档又不说,浪费很多时间。

慢慢读它的文档,发现提供了fileObj 属性定制upload file name,不给默认 Filedata。(MD,真是大坑,有这么默认的吗?)

fileObjName

Input TypeString

Default Value'Filedata'

The name of the file object to use in your server-side script.  For example, in PHP, if this option is set to ‘the_files’, you can access the files that have been uploaded using $_FILES[‘the_files’];

 修改js代码,添加属性fileObjName,解决问题。

    $(function() {
        $('#file_upload').uploadifive({
            'fileObjName'  : 'file_upload',
            'uploadScript' : '/upload'
            // Put your options here
        });
    });

 

参考文献:

http://www.uploadify.com/documentation/uploadifive/implementing-uploadifive/

http://www.uploadify.com/documentation/uploadifive/fileobjname-2/

https://www.cnblogs.com/magicalSam/p/7189476.html

https://www.cnblogs.com/smiler/p/6857167.html

 

源代码下载:

https://github.com/adorechen/uploadify_demo

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值