• Spring MVC使用commons fileupload实现文件上传功能


    通过Maven建立Spring MVC项目,引入了Spring相关jar依赖。

    1、为了使用commons fileupload组件,需要在pom.xml中添加依赖;

      <properties>
            <spring.version>3.0.7.RELEASE </spring.version>
            <junit.version>3.8.1</junit.version>
            <fileupload.version>1.2.2</fileupload.version>
        </properties>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>${fileupload.version}</version>
        </dependency>

    2、配置Spring MVC,项目成功启动后,编写jsp页面;

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            <title>Errors导入Excel</title>
        </head>
        <body>
            <div>
                <!--只有将表单的enctype设置为multipart/form-data,才能实现文件上传;表单enctype的默认值为:application/x-www-form-urlencoded-->
                <!--只有POST方法才会被解析为文件上传请求    -->
                <form action="./fileupload" method="post" enctype="multipart/form-data">
                    <!-- 不知道为啥,type="file"这一标签必须同时添加name属性,否则在处理上传时,无法检测到上传文件 -->
                    <input type="file" name="fileField"/>
                    <input type="submit" value="上传"/>                 
                </form>
                <p><font color="red">上传文件大小限制在1M之内</font></p>
            </div>
        </body>
    </html>

    注:注释当中的内容还是很重要的,使用时遇到了比较多奇葩的问题,暂时还未弄明白原因,留待日后解决。
    注:实现上传文件的表单,需要指定method="post"且enctype="multipart/form-data",否则无法通过fileupload组件解析为上传请求。

    3、编写Controller,名为FileUploadController,在Controller中对上传文件进行处理;

     1 @Controller
     2 public class FileUploadController {
     3     
     4     @RequestMapping("/fileupload")
     5     public String handleFileUpload(HttpServletRequest request){
     6         boolean flag = false;
     7         
     8         //判断是否是文件上传请求
     9         if(ServletFileUpload.isMultipartContent(request)){
    10             // 创建文件上传处理器
    11             ServletFileUpload upload = new ServletFileUpload();
    12             //限制单个上传文件的大小
    13             upload.setFileSizeMax(1L<<24);
    14             
    15             try {
    16                 // 解析请求
    17                 FileItemIterator iter = upload.getItemIterator(request);
    18                 
    19                 while (iter.hasNext()) {
    20                     FileItemStream item = iter.next();
    21                     
    22                     if (!item.isFormField()) {
    23                         //是文件上传对象,获取上传文件的输入流
    24                         InputStream srcinInputStream = item.openStream();
    25                         /*对上传文件的输入流进行处理,跟本地的文件流处理方式相同*/
    26                         
    27                     }
    28                 }
    29             } catch (FileUploadException e) {
    30                 System.out.println("上传文件过大");
    31             } catch (IOException e) {
    32                 System.out.println("文件读取出现问题");
    33             }
    34         }
    35         
    36         return flag? "success":"error";
    37     }
    38 }

    注:commons fileupload的用户指南 http://commons.apache.org/proper/commons-fileupload/using.html;
    注:判断上传请求及处理使用了Streaming API http://commons.apache.org/proper/commons-fileupload/streaming.html;
    内容如下:

    注:第一次看commons fileupload组件的用户指南时,感觉无从下手,其实User Guide的Parsing the request部分已经给出了很明确的说明。可以通过在对应的请求处理方法中直接通过ServletFileUpload.isMultipartContent(request)来判断是否是文件上传请求,通过 !item.isFormField() 来判断是否是文件上传对象;

    4、fileupload组件上传文件时,获取普通域参数值和文件域输入流;
    html元素的form表单的enctype属性规定在发送到服务器之前应该如何对表单数据进行编码。表单的enctype默认值为 "application/x-www-form-urlencoded",在表单发送到服务器之前,所有字符都会进行编码(空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值);对于文件上传,form表单的enctype="multipart/form-data",此时form表单不对字符编码,此时在请求的处理函数中无法通过request.getParameter("parameterName")来获取参数值;

    但是可以通过其他方式来获取参数值;

     1   /**
     2      * 获取页面传递的参数,以Map存储,以fieldName为键值,普通域存储value,文件上传域存储文件输入流
     3      * @param request
     4      * @return
     5      */
     6     private Map<String, Object> getParameters(HttpServletRequest request){
     7         Map<String, Object> parameters = new HashMap<String, Object>();
     8         
     9         // 默认最多允许存储1024个字节
    10         DiskFileItemFactory factory = new DiskFileItemFactory();
    11         
    12         if(ServletFileUpload.isMultipartContent(request)){
    13             ServletFileUpload upload = new ServletFileUpload(factory);
    14             
    15             try{
    16                 List<FileItem> items =upload.parseRequest(request);
    17             
    18                 for(Iterator<FileItem> iter = items.iterator(); iter.hasNext();){
    19                     FileItem item = iter.next();
    20                     
    21                     if(item.isFormField()){
    22                         //普通域,取参数值
    23                         parameters.put(item.getFieldName(), item.getString());
    24                     }else{
    25                         //文件上传域,取输入流
    26                         parameters.put(item.getFieldName(), item.getInputStream());
    27                     }
    28                 }
    29             }catch(Exception exception){
    30                 exception.printStackTrace();
    31             }
    32         }
    33         
    34         return parameters;
    35     }
  • 相关阅读:
    HTML多余字符省略号显示,获取jstl表达式传过来的值(内容)
    去除layui表头右边的功能键
    常用正则表达式
    layui注册页面
    怎样将写入到input框中的数据显示到页面上
    layui 添加功能
    python3 -- 去除字符串头尾字符 strip()
    Linux -- tar 命令
    PyMySql -- 常用方法
    MySQL -- 目录
  • 原文地址:https://www.cnblogs.com/-crazysnail/p/3923135.html
Copyright © 2020-2023  润新知