Spring MVC 文件上传的示例代码

发布时间 - 2026-01-11 03:23:41    点击率:

一如既往记录下常用而又容易忘记的东西,本篇博文主要针对Spring MVC是如何上传文件的。以下记录两种上传方法并针对案例进行记录。(有关spring mvc其他配置省略)

1、使用Spring MVC 上传文件必须配置文件解析器,如下:

<!-- 上传文件拦截,设置最大上传文件大小 10M=10*1024*1024(B)=10485760 bytes --> 
 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
  <property name="maxUploadSize" value="10485760" /> 
  <property name="maxInMemorySize" value="10240000" /> 
  <property name="defaultEncoding" value="UTF-8" />
 </bean>

2、建立上传文件表单代码,其中要注意form表单中的enctype 属性,必须存在且必须为multipart/form-data。还有当form中存在button标签时,用ajax异步提交表单后,也面会被刷新。原因:button 存在时会再次提交一下表单,所以页面被刷新了。

<!-- 
  enctype 属性值:
    1、application/x-www-form-urlencoded 在发送前编码所有字符(默认)
    2、multipart/form-data 不对字符编码。 在使用包含文件上传控件的表单时,必须使用该值。
    3、text/plain 空格转换为 "+" 加号,但不对特殊字符编码。
-->
<div class="row">
  <form method="post" enctype="multipart/form-data" id="form1">
    <div><label>1、采用流的方式</label></div>
    <div class="col-sm-7" style="padding-left:0px">
      <div class="input-group">
        <input type="text" class="form-control" id="showFileInput1">
        <input type="file" style="display:none" name="txtFile" id="uploadFileInput1" accept="text/plain">
        <span class="input-group-addon" id="uploadFileButton1">
          <span class="glyphicon glyphicon-folder-open"></span>
          <label>浏览</label>
        </span>
      </div>
    </div>
    <div class="col-sm-5">
      <!-- 
                  当form中存在button标签时,用ajax异步提交表单后,也面会被刷新。(感觉很诡异)
                  原因:button 存在时会再次提交一下表单,所以页面被刷新了。(之前认为button type='submit' 时)button才有提交表单的功能。
      -->
      <a class="btn btn-default" id="submit1">上传</a>
    </div>
  </form>
</div>

 3.1、使用CommonsMultipartFile接收上传文件,其中要注意的是:方法中CommonsMultipartFile对应的变量名如果不是对应表单中文件输入框<input type="file" style="display:none" name="txtFile" id="uploadFileInput1" accept="text/plain">的名称就必须加上@RequestParam("txtFile") 强制注入。

 /**
   * @Description: 通过文件流的形式上传
   * @param file  @RequestParam("txtFile") 将name=txtFile控件得到的文件封装成CommonsMultipartFile对象,
   *       如果不这样做会报CommonsMultipartFile没有初始化的错误
   *       java.lang.NoSuchMethodException: org.springframework.web.multipart.commons.CommonsMultipartFile.<init>()
   * @return
   * @author yuanfy
   * @date 2017年9月15日 下午4:36:11 
   * @version 6.5
   */
  @RequestMapping(value="test/upload1")
  @ResponseBody
  public String testUpload1(@RequestParam("txtFile")CommonsMultipartFile file){
    Long times = System.currentTimeMillis();
    if (file == null) {
      return null;
    }
    StringBuilder fileContent = new StringBuilder();
    //1、获取文件信息
    FileUtils.getFileInfo(file, fileContent);
    
    //2、上传文件并获取文件内容
    try {
      file.transferTo(new File("F:\\text.log"));//另存文件
      fileContent.append(FileUtils.getFileContentByLine(file.getInputStream()));
    }
    catch (IOException e) {
      return "获取文件内容失败";
    }
    
    //3、返回文件信息和内容
    String content = fileContent.toString();
    content = content.replace("times", (System.currentTimeMillis()-times) + "ms");
    return content;
  }

  界面效果图如下:

3.2、使用CommonsMultipartResolver获取存放文件对象,拿到文件对象后遍历每个文件上传及获取相关的内容。

@RequestMapping(value="test/upload2")
  @ResponseBody
  public String testUpload2(HttpServletRequest request){
    Long times = System.currentTimeMillis();
    StringBuilder fileContent = new StringBuilder();
    //1.根据servletContext获取多文件上传解析组件
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
    if (!multipartResolver.isMultipart(request)) {
      return "不是上传文件表单,请检查表单属性";
    }
    //2.将请求对象转换为多文件请求对象。
    MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
    //3、根据多文件请求对象获取文件存放Map
    Map<String, MultipartFile> fileMap = multipartHttpServletRequest.getFileMap();
    Iterator<Entry<String, MultipartFile>> iterator = fileMap.entrySet().iterator();
    //4、迭代文件Map,获取具体的MultipartFile
    while (iterator.hasNext()) {
      Entry<String, MultipartFile> entry = iterator.next();
      MultipartFile multipartFile = entry.getValue();
      //获取文件头信息
      FileUtils.getFileInfo(multipartFile, fileContent);
      try {
        //上传文件
        multipartFile.transferTo(new File("F:\\text.log"));
        //获取文件内容
        fileContent.append(FileUtils.getFileContentByLine(multipartFile.getInputStream()));
      }catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    //5、返回文件信息和内容
    String content = fileContent.toString();
    content = content.replace("times", (System.currentTimeMillis()-times) + "ms");
    return content;
  }

其中第一步获取文件解析器对象应该都清楚只要在容器中配置了对应的对象我们就可以获取到它,而它有根据上下文获取的构造函数就方便多了。

/**
   * Constructor for standalone usage. Determines the servlet container's
   * temporary directory via the given ServletContext.
   * @param servletContext the ServletContext to use
   */
  public CommonsMultipartResolver(ServletContext servletContext) {
    this();
    setServletContext(servletContext);
  }

然后根据request判断是否还有上传文件的表单,如果不是肯定直接返回,我们看看源码中是怎么判断的。

//CommonsMultipartResolver.class 主要判断request是否为空
@Override
public boolean isMultipart(HttpServletRequest request) {
  return (request != null && ServletFileUpload.isMultipartContent(request));
}  
//ServletFileUpload 主要判断是否是post方法,因为上传文件必须是post提交,其实我们可以在我们自定义controller中的方法指定访问
public static final boolean isMultipartContent(HttpServletRequest request) {
  if (!POST_METHOD.equalsIgnoreCase(request.getMethod())) {
      return false;
    }
    return FileUploadBase.isMultipartContent(new ServletRequestContext(request));
}
//FileUploadBase.class 如果请求是MULTIPART 则返回true
public static final boolean isMultipartContent(RequestContext ctx) {
    String contentType = ctx.getContentType();//类似:multipart/form-data; boundary=----WebKitFormBoundaryLF3eM94lDB0ocQxT
    if (contentType == null) {
      return false;
    }
    if (contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART)) {
      return true;
    }
    return false;
}

所以如果request是上传文件的请求对象,则进行第二步。将request转换成多文件请求对象,然后获取存放文件的map。

可想而知这种方法效率是比第一种要低的,因为他要遍历文件map,但是在Spring MVC常用的却是这种方法。

效果图如下:

其中FileUtils.java代码如下:

package com.yuanfy.monitorsite.common.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import org.springframework.web.multipart.MultipartFile;

/**
 * @Description: 文件工具类方法
 * @author yuanfy
 * @date 2017年9月15日 下午2:45:40 
 * @version 1.0
 */
public class FileUtils {
  /**
   * @Description: 获取文件信息
   * @param file CommonsMultipartFile类型的文件
   * @param fileContent StringBuilder,封装文件信息
   * @author yuanfy
   * @date 2017年9月15日 下午2:51:34 
   * @version 1.0
   */
  public static void getFileInfo(MultipartFile file, StringBuilder fileContent) {
    fileContent.append("文件名称:\t\t").append(file.getName()).append("\n")
      .append("文件原始名称:\t").append(file.getOriginalFilename()).append("\n")
      .append("文件大小:\t\t").append(file.getSize()).append("\n")
      .append("文件类型:\t\t").append(file.getContentType()).append("\n")
      .append("读取文件时长:\t times").append("\n");
  }
  
  /**
   * @Description: 根据文件对象获取文件内容
   * @param file
   * @author yuanfy
   * @date 2017年9月15日 下午5:01:57 
   * @version 1.0
   * @throws IOException 
   * @throws FileNotFoundException 
   */
  public static String getFileContentByLine(File file) throws FileNotFoundException, IOException {
    return getFileContentByLine(new FileInputStream(file));
  }
  /**
   * @Description: 根据文件输入流对象获取文件内容
   * @param in 文件输入流对象
   * @author yuanfy
   * @date 2017年9月15日 下午5:01:57 
   * @version 1.0
   * @throws IOException 
   */
  public static String getFileContentByLine(InputStream in) throws IOException {
    StringBuilder fileContent = new StringBuilder();
    
    byte[] bytes = new byte[1024];
    int len = 0;
    while ((len = in.read(bytes)) != -1) {
      String content = new String(bytes, 0, len, "UTF-8");
      fileContent.append(content);
    }
    StreamUtils.close(in);
    return fileContent.toString();
  }
}

当然要想查看整个代码,可以访问我项目的整个代码:https://github.com/YuanFY/blog_demo。

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


# Spring  # MVC  # 文件上传  # springmvc  # SpringMVC文件上传 多文件上传实例  # Spring MVC中上传文件实例  # springMVC配置环境实现文件上传和下载  # SpringMVC文件上传的配置实例详解  # springMVC结合AjaxForm上传文件  # springMVC实现前台带进度条文件上传的示例代码  # spring mvc实现文件上传并携带其他参数的示例  # 在SpringMVC框架下实现文件的上传和下载示例  # SpringMVC上传文件的三种实现方式  # 表单  # 上传文件  # 下午  # 上传  # 遍历  # 要注意  # 如果不是  # 会报  # 转换为  # 的是  # 判断是否  # 这种方法  # 却是  # 是怎么  # 两种  # 我们可以  # 要想  # 这样做  # 才有 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何在阿里云部署织梦网站?  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  iOS验证手机号的正则表达式  Laravel怎么在Controller之外的地方验证数据  香港服务器建站指南:免备案优势与SEO优化技巧全解析  Python自动化办公教程_ExcelWordPDF批量处理案例  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  使用PHP下载CSS文件中的所有图片【几行代码即可实现】  Laravel怎么设置路由分组Prefix_Laravel多级路由嵌套与命名空间隔离【步骤】  大连 网站制作,大连天途有线官网?  如何快速搭建二级域名独立网站?  悟空识字如何进行跟读录音_悟空识字开启麦克风权限与录音  Android仿QQ列表左滑删除操作  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】  Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能  网站制作软件有哪些,制图软件有哪些?  java中使用zxing批量生成二维码立牌  如何确保西部建站助手FTP传输的安全性?  桂林网站制作公司有哪些,桂林马拉松怎么报名?  JavaScript实现Fly Bird小游戏  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  香港服务器WordPress建站指南:SEO优化与高效部署策略  Python正则表达式进阶教程_复杂匹配与分组替换解析  laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法  js实现获取鼠标当前的位置  Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】  成都网站制作公司哪家好,四川省职工服务网是做什么用?  如何在阿里云服务器自主搭建网站?  Laravel如何构建RESTful API_Laravel标准化API接口开发指南  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  Laravel如何使用Eloquent进行子查询  微信小程序 input输入框控件详解及实例(多种示例)  Firefox Developer Edition开发者版本入口  JS中页面与页面之间超链接跳转中文乱码问题的解决办法  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  JS弹性运动实现方法分析  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率  公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?  如何在景安服务器上快速搭建个人网站?  JavaScript如何实现错误处理_try...catch如何捕获异常?  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  phpredis提高消息队列的实时性方法(推荐)  如何解决hover在ie6中的兼容性问题  为什么要用作用域操作符_php中访问类常量与静态属性的优势【解答】  Android使用GridView实现日历的简单功能  为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】  浅谈javascript alert和confirm的美化  如何在服务器上配置二级域名建站?