SpringMVC通过StandardServletMultipartResolver实现文件上传

本文介绍了SpringMVC中通过StandardServletMultipartResolver处理multipart请求的方法,该实现依赖于Servlet 3.0+。讨论了XML配置、Controller设置,并指出在表单提交时需要注意的细节,包括form的enctype属性、HTTP方法和bean的id。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

    从Spring3.1开始,Spring提供了两个MultipartResolver的实现用于处理multipart请求。

    它有两个实现类:

  •  CommonsMultipartResolver:依赖于Apache下的jakarta Common FileUpload项目解析Multipart请求,可以再SPring的各个版本中使用,只是它要依赖于第三方包才得以实现。
  • StandardServletMultipartResolver:是Spring3.1版本后的产物,它依赖于Servlet3.0+的实现,它不用依赖第三方包。

MultipartResolver

      在Spring中,既可以通过XML,也可以通过Java去配置MultipartResolver。对于StandardServletMultipartResolver,它的构造方法没有参数,所以很容易对其进行初始化。下面介绍XML的配置方式,在配置DispatcherServlet的地方进行配置。

    <servlet>
        <servlet-name>dispatcher</servlet-name>x
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
        <multipart-config>
            <!--临时文件的目录-->
            <location>d:/tmp/</location>
            <!-- 上传文件最大2M -->
            <max-file-size>2097152</max-file-size>
            <!-- 上传文件整个请求不超过4M -->
            <max-request-size>4194304</max-request-size>
        </multipart-config>
    </servlet>

要注意xml中web-app节点使用的版本,必须是3.0+。

接下来通过XML或者注解生成一个StandardServletMultipartResolver便可以了。

<bean id="multipartResolver"
    class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</bean>

此处的bean的id必须为'multipartResolver',此为Spring的约定,否则可能会导致Controller接受到null。

Controller设置

@Controller
@RequestMapping("/fileupload")
public class FileController {

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ModelAndView loadMultipartFile(MultipartFile file) {
        ModelAndView mv = new ModelAndView();

        mv.setView(new MappingJackson2JsonView());

        String fileName = file.getOriginalFilename();

        file.getContentType();

        File dest = new File(fileName);

        try {
            file.transferTo(dest);

            mv.addObject("success", true);
            mv.addObject("msg", "上传文件成功");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            return mv;
        }
    }

    @RequestMapping("/uploadPart", method = RequestMethod.POST)
    public ModelAndView uploadPart(Part file) {
        ModelAndView mv = new ModelAndView();

        mv.setView(new MappingJackson2JsonView());
        String fileName = file.getSubmittedFileName();
        File dest = new File(fileName);

        try {
            file.write("d:/tmp/" + fileName);

            mv.addObject("success", true);
            mv.addObject("msg", "上传文件成功");
        } catch (IOException e) {
            mv.addObject("success", false);
            mv.addObject("msg", "上传文件失败");
            e.printStackTrace();
        }

        return mv;
    }
}

两种方法大同小异。

form表单

<form action="/fileupload/uploadPart.do" method="post" enctype="multipart/form-data">
    <input type="file" id="file" name="file" value="请选择上传"/>
    <input type="submit" value="提交"/>
</form>

借着form表单开始说我遇到的问题。

Controller接收到的参数MultipartFile为null,导致后面抛出空指针异常,百度中的方法都试过,没用。

将表单加入一个input一起提交,Controller却能收到。

最后将表单的提交方法设置成POST,参数正常也实现了保存的功能。

虽然不知道更深层次的原因,但是从中可以看到编码规范的重要性。

然后在注解上限定为post提交

    @RequestMapping("/uploadPart", method = RequestMethod.POST)

加上后,如果再犯表单没加method='post',会报405错误,从而快速定位问题。


其他可能会导致为null的原因。

1.form没加enctype="multipart/form-data"

2.bean的id不为multipartResolver

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值