欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringMVC 单文件上传与多文件上传实例

程序员文章站 2023-12-11 19:15:40
一、简述 一个javaweb项目中,文件上传功能几乎是必不可少的,本人在项目开发中也时常会遇到,以前也没怎么去理它,今天有空学习了一下这方面的知识,于是便将本人学到的sp...

一、简述

一个javaweb项目中,文件上传功能几乎是必不可少的,本人在项目开发中也时常会遇到,以前也没怎么去理它,今天有空学习了一下这方面的知识,于是便将本人学到的springmvc中单文件与多文件上传这部分知识做下笔记。

二、单文件上传

1、页面

这里以一个简单的表单提交为例子,文件上传需要将表单的提交方法设置为post,将enctype的值设置为"multipart/form-data"。

<form action="${pagecontext.request.contextpath}/test/upload.do" method="post" enctype="multipart/form-data">
  <input type="file" name="img"><br /> 
  <input type="submit" name="提交">
</form>

2、控制器

在controller的处理方法中,使用multipartfile对象作为参数接收前端上传过来的文件,具体说明请看代码注释。

@controller
@requestmapping("/test")
public class mycontroller {

  @requestmapping(value = "/upload.do", method = requestmethod.post)
  // 这里的multipartfile对象变量名跟表单中的file类型的input标签的name相同,所以框架会自动用multipartfile对象来接收上传过来的文件,当然也可以使用@requestparam("img")指定其对应的参数名称
  public string upload(multipartfile img, httpsession session)
      throws exception {
    // 如果没有文件上传,multipartfile也不会为null,可以通过调用getsize()方法获取文件的大小来判断是否有上传文件
    if (img.getsize() > 0) {
      // 得到项目在服务器的真实根路径,如:/home/tomcat/webapp/项目名/images
      string path = session.getservletcontext().getrealpath("images");
      // 得到文件的原始名称,如:美女.png
      string filename = img.getoriginalfilename();
      // 通过文件的原始名称,可以对上传文件类型做限制,如:只能上传jpg和png的图片文件
      if (filename.endswith("jpg") || filename.endswith("png")) {
        file file = new file(path, filename);
        img.transferto(file);
        return "/success.jsp";
      }
    }
    return "/error.jsp";
  }
}

3、springmvc.xml配置

使用multipartfile对象接收前端上传过来的文件,还需要在springmvc的配置文件中进行如下配置:

<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemalocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

  ...

  <!-- 注意:commonsmultipartresolver的id是固定不变的,一定是multipartresolver,不可修改 -->
  <bean id="multipartresolver" class="org.springframework.web.multipart.commons.commonsmultipartresolver">
    <!-- 如果上传后出现文件名中文乱码可以使用该属性解决 -->
    <property name="defaultencoding" value="utf-8"/>
    <!-- 单位是字节,不设置默认不限制总的上传文件大小,这里设置总的上传文件大小不超过1m(1*1024*1024) -->
    <property name="maxuploadsize" value="1048576"/>
    <!-- 跟maxuploadsize差不多,不过maxuploadsizeperfile是限制每个上传文件的大小,而maxuploadsize是限制总的上传文件大小 -->
    <property name="maxuploadsizeperfile" value="1048576"/>
  </bean>

  <!-- 设置一个简单的异常解析器,当文件上传超过大小限制时跳转 -->
  <bean class="org.springframework.web.servlet.handler.simplemappingexceptionresolver">
    <property name="defaulterrorview" value="/error.jsp"/>
  </bean>
</beans>

上面配置文件中的commonsmultipartresolver下的属性值配置不是必须的,你也可以全部不写。到这里就可以实现单个文件上传了,下面来看看多文件上传。

三、多文件上传

其实多文件上传也很简单,单文件上传是在controller的处理方法中使用multipartfile对象作为参数接收前端上传过来的文件,而多文件上传则使用multipartfile对象数组来接收。

1、页面

该页面中有几个name值一样的file类型的input标签,其他跟单文件上传的页面没差。

<form action="${pagecontext.request.contextpath}/test/upload.do" method="post" enctype="multipart/form-data">
  file 1 : <input type="file" name="imgs"><br /> 
  file 2 : <input type="file" name="imgs"><br /> 
  file 3 : <input type="file" name="imgs"><br /> 
  <input type="submit" name="提交">
</form>

2、控制器

控制器中的处理方法使用multipartfile[]数组作为接收参数,并不能直接使用,需要校正参数,具体说明请看代码注释。

@controller
@requestmapping("/test")
public class mycontroller {

  @requestmapping(value = "/upload.do", method = requestmethod.post)
  // 这里的multipartfile[] imgs表示前端页面上传过来的多个文件,imgs对应页面中多个file类型的input标签的name,但框架只会将一个文件封装进一个multipartfile对象,
  // 并不会将多个文件封装进一个multipartfile[]数组,直接使用会报[lorg.springframework.web.multipart.multipartfile;.<init>()错误,
  // 所以需要用@requestparam校正参数(参数名与multipartfile对象名一致),当然也可以这么写:@requestparam("imgs") multipartfile[] files。
  public string upload(@requestparam multipartfile[] imgs, httpsession session)
      throws exception {
    for (multipartfile img : imgs) {
      if (img.getsize() > 0) {
        string path = session.getservletcontext().getrealpath("images");
        string filename = img.getoriginalfilename();
        if (filename.endswith("jpg") || filename.endswith("png")) {
          file file = new file(path, filename);
          img.transferto(file);
        }
      }
    }
    return "/success.jsp";
  }
}

同样的,使用multipartfile数组接收前端上传过来的多个文件,也需要在springmvc的配置文件进行配置,具体配置与上述单文件上传的springmvc.xml配置没差,直接拷贝过来就行。这样,就可以进行多文件上传了。

四、多种文件上传情景综合

当然,项目开发中,场景可能并不是这么简单,上述的多文件上传是一个个文件选择后一起上传(即多个name相同的input标签),那要是我项目中只要一个input标签就可以一次性多个文件呢?又或者一个页面中既要一个个选择的多文件上传,又要一次性选择的多文件上传,还要有单文件上传呢?没问题,multipartfile[]通吃,代码也很easy,下面直接上代码。

1、页面

这里的 “一次选择多个文件的多文件上传” 只是在input标签中加上了multiple属性而已。

<form action="${pagecontext.request.contextpath}/test/upload.do" method="post" enctype="multipart/form-data">

  一次选择多个文件的多文件上传 : <br /> 
  <input type="file" name="imgs1" multiple><br /> <br /> 

  一次选择一个文件的多文件上传 : <br /> 
  <input type="file" name="imgs2"><br /> 
  <input type="file" name="imgs2"><br /><br /> 

  单文件上传 : <br /> 
  <input type="file" name="imgs3"><br /><br /> 
  <input type="submit" name="提交">
</form>

2、控制器

@controller
@requestmapping("/test")
public class mycontroller {

  @requestmapping(value = "/upload.do", method = requestmethod.post)
  public string upload(@requestparam multipartfile[] imgs1,@requestparam multipartfile[] imgs2,@requestparam multipartfile[] imgs3, httpsession session)
      throws exception {
    string path = session.getservletcontext().getrealpath("images");
    for (multipartfile img : imgs1) {
      uploadfile(path, img);
    }
    for (multipartfile img : imgs2) {
      uploadfile(path, img);
    }
    for (multipartfile img : imgs3) {
      uploadfile(path, img);
    }
    return "/success.jsp";
  }

  private void uploadfile(string path, multipartfile img) throws ioexception {
    if (img.getsize() > 0) {
      string filename = img.getoriginalfilename();
      if (filename.endswith("jpg") || filename.endswith("png")) {
        file file = new file(path, filename);
        img.transferto(file);
      }
    }
  }
}

multipartfile[]就是如此强大,不管单个多个,逻辑处理一样,所以建议在项目开发中使用multipartfile[]作为文件的接收参数。

五、拓展

1、multipartfile类常用的一些方法:

string getcontenttype()//获取文件mime类型
inputstream getinputstream()//获取文件流
string getname() //获取表单中文件组件的名字
string getoriginalfilename() //获取上传文件的原名
long getsize() //获取文件的字节大小,单位byte
boolean isempty() //是否为空
void transferto(file dest)

2、commonsmultipartresolver的属性解析

  1. defaultencoding:表示用来解析request请求的默认编码格式,当没有指定的时候根据servlet规范会使用默认值iso-8859-1。当request自己指明了它的编码格式的时候就会忽略这里指定的defaultencoding。
  2. uploadtempdir:设置上传文件时的临时目录,默认是servlet容器的临时目录。
  3. maxuploadsize:设置允许上传的总的最大文件大小,以字节为单位计算。当设为-1时表示无限制,默认是-1。
  4. maxuploadsizeperfile:跟maxuploadsize差不多,不过maxuploadsizeperfile是限制每个上传文件的大小,而maxuploadsize是限制总的上传文件大小。
  5. maxinmemorysize:设置在文件上传时允许写到内存中的最大值,以字节为单位计算,默认是10240。
  6. resolvelazily:为true时,启用推迟文件解析,以便在uploadaction中捕获文件大小异常。

六、注意

  1. 在开发过程中,建议把配置文件中的异常解析器(simplemappingexceptionresolver)先注释掉,方便我们查看错误。
  2. 有时候上传出错,是因为我们在配置文件中限制了上传文件的大小,你可以不加这个限制,但个人建议这个限制最好还是加上,具体文件大小限制请根据公司项目情况而定。
  3. springmvc中使用multipartfile接收上传文件需要依赖两个jar包,分别是:commons-fileupload-1.3.3.jar、commons-io-2.5.jar。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: