• spring实现文件上传(图片解析)


    合抱之木,生于毫末,千里之行,始于足下,要想了解spring的文件上传功能,首先要知道spring是通过流的方式将文件进行解析,然后上传。那么是不是所有需要用的文件上传的地方都要写一遍文件解析器呢?

    放心,spring这个大管家已经为我们做好了一切!

    我们只需要在spring的配置文件中加入下面代码:

     <!-- 文件上传解析器 -->
        <bean id="multipartResolver"
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
            p:maxUploadSize="152400" 
            p:defaultEncoding="utf-8">
            <!-- <property name="defaultEncoding" value="utf-8"></property> -->
        </bean>
        
        <!-- SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException -->  
        <!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,而且此时还没有进入到Controller方法中 -->  
        <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
            <property name="exceptionMappings">  
                <props>  
                    <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 -->  
                    <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload</prop>  
                </props>  
            </property>  
        </bean>

    我们就不用再去在文件的解析上绞尽脑汁了,只需要专注于业务层面的逻辑就好了,是不是很简单?

    接下来我们看一个小例子:

    html前端代码:

    <%@ 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>Insert title here</title>
    </head>
    <body>
    
    <form action="<%=request.getContextPath()%>/user/add" method="post" enctype="multipart/form-data">
        
        
        <h1>新增用户</h1>
        
        <table>
            <tr>
                <td>用户名:</td>
                <td>
                    <input type="text" name="userName" value="${user.userName }" />
                </td>
            </tr>
            <tr>
                <td>密码:</td>
                <td>
                    <input type="text" name="password" value="${user.userPass }" />
                </td>
            </tr>
            <tr>
                <td>头像:</td>
                <td>
                    <input type="file" name="photo" />
                </td>
            </tr>
            <tr>
                <td></td>
                <td>
                    <input type="submit" value="上传" />
                </td>
            </tr>
        </table>
    </form>
    
    </body>
    </html>

    大家有没有注意到以上代码的form表头中有一行代码:

    enctype="multipart/form-data"

    没错,想要上传二进制文件,该表头属性必不可少。
    controller控制层代码:
    package com.wskj.springmvc.controller;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    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 com.wskj.springmvc.pojo.UserInfo;
    
    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        @RequestMapping(value="/add", method=RequestMethod.GET)
        public String addUser(){
            
            return "user/add";
        }
        
        @RequestMapping(value="/add", method=RequestMethod.POST)
        public String addUser(Model model, UserInfo user, @RequestParam(name="photo", required=false) MultipartFile photo, HttpServletRequest request) throws IOException{
            
            //对文件进行处理
            
            //判断用户是否上传了文件
            //MultipartFile.getSize() : 获取文件的大小(字节:byte)  1024byte = 1kb   1024kb=1mb   GB  TB  PB
            if(photo.isEmpty() == false && photo.getSize() > 0){
                
                //获取文件的名称
                String name = photo.getName();//photo
                String fileName = photo.getOriginalFilename();//mydata.jpg
                //获取文件扩展名
                String extension = fileName.substring(fileName.lastIndexOf("."));
                
                byte[] data = photo.getBytes();//字节数组
                String contentType = photo.getContentType();
                /**
                 * 扩展名      Content-Type
                 * .txt     text/plain
                 * .jpg  image/jpeg
                 * .mp3     audio/mp3
                 * .mp4     video/mpeg4
                 */
                
                photo.getInputStream();//获取文件输入流
                
                //保存到磁盘
                //保存的路径
                //不是 -》 F:javaworkspacespringspringmvc_fileupload_20170401WebContentfiles
                //是 -》 x:apache tomcat-7webappsappNamefiles
                String savedPath = request.getServletContext().getRealPath("files");//获取files目录的绝对路径
                String filePath = savedPath + "/" + fileName;
                
                //将文件写入磁盘
                photo.transferTo(new File(filePath));
                
                //设置UserInfo.headerPhoto
                user.setHeaderPhotoUrl("files/"+fileName);
                model.addAttribute("headerUrl", user.getHeaderPhotoUrl());
            }
            
            model.addAttribute("user", user);
            
            return "user/success";
        }
        
        @RequestMapping(value="/add2", method=RequestMethod.GET)
        public String addUser2(){
            
            return "user/add2";
        }
        
        @RequestMapping(value="/add2", method=RequestMethod.POST)
        public String addUser2(Model model, UserInfo user, @RequestParam(name="photos", required=false) MultipartFile[] photos, HttpServletRequest request) throws IOException{
            
            //对文件进行处理
            
            if(photos != null && photos.length>0){
                List<String> photoUrls = new ArrayList<String>();
                for(MultipartFile photo : photos){
                    
                    //判断用户是否上传了文件
                    //MultipartFile.getSize() : 获取文件的大小(字节:byte)  1024byte = 1kb   1024kb=1mb   GB  TB  PB
                    if(photo.isEmpty() == false && photo.getSize() > 0){
                        
                        //获取文件的名称
                        String name = photo.getName();//photo
                        String fileName = photo.getOriginalFilename();//mydata.jpg
                        //获取文件扩展名
                        String extension = fileName.substring(fileName.lastIndexOf("."));
                        
                        byte[] data = photo.getBytes();//字节数组
                        String contentType = photo.getContentType();
                        /**
                         * 扩展名      Content-Type
                         * .txt     text/plain
                         * .jpg  image/jpeg
                         * .mp3     audio/mp3
                         * .mp4     video/mpeg4
                         */
                        
                        photo.getInputStream();//获取文件输入流
                        
                        //保存到磁盘
                        //保存的路径
                        //不是 -》 F:javaworkspacespringspringmvc_fileupload_20170401WebContentfiles
                        //是 -》 x:apache tomcat-7webappsappNamefiles
                        String savedPath = request.getServletContext().getRealPath("files");//获取files目录的绝对路径
                        String filePath = savedPath + "/" + fileName;
                        
                        //将文件写入磁盘
                        photo.transferTo(new File(filePath));
                        
                        //设置UserInfo.headerPhoto
                        
                        photoUrls.add("files/"+fileName);
                    }
                    
                }
                
                model.addAttribute("headerUrl", photoUrls);
            
            }
            
            model.addAttribute("user", user);
            
            return "user/success2";
        }
        
    }

    后台根据前段的name属性接收参数,二进制文件类型为

    MultipartFile,如果需要接收多个文件,只需要设置成集合然后遍历即可。
    接下来是上传成功前段回显的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>Insert title here</title>
    </head>
    <body>
    
        <dl>
            <dt>用户名:</dt>
            <dd>${user.userName }</dd>
            <dt>头像:</dt>
            <dd>
                <img style="max-300px;max-height:200px;" src="<%=request.getContextPath() %>/${headerUrl}" />
            </dd>
        </dl>
    
    </body>
    </html>

    至此,最基础的文件上传测试成功。

    但是,在实际项目中,我们可能只是需要启用一个div来进行文件的异步上传,这时我们可以使用html5的新特性formdata实现ajax的提交。

    具体代码如下:

    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>Insert title here</title>
    <script type="text/javascript" src="<%= request.getContextPath()%>/static/jquery-1.10.2.js"></script>
    <script type="text/javascript">
    
    $(function(){
    
        $("#btnupload").click(function(){
            
            var formdata = new FormData(document.getElementById("form1"));//可以上传文件
            //var formdata = $("#form1").serializeArray();//无法上传文件的
            alert(formdata);
            var url ="<%= request.getContextPath()%>/upload/demo1";
            $.ajax({
                url:url,
                data:formdata, //name=zhangsan&age=50   {}
                contentType: false,//默认: "application/x-www-form-urlencoded"
                processData: false,//设置 processData 选项为 false,防止自动转换数据格式
                type:"post",
                dataType:"json",
                success:function(data){
                    alert(data);
                },
                error:function(er){
                    alert(er.responseText);
                }
            });
            
            
        });
    });
    
    </script>
    
    </head>
    <body>
    
        <h1>使用Html5提供的FormData实现ajax提交</h1>
        <h3>浏览器必须支持html5,如果是IE6 - IE8,那就洗洗睡吧...</h3>
    
        <form id="form1">
            文件名:<input type="text" name="fileName" />
            文件:<input type="file" name="myfile" />
            <input id="btnupload" type="button" value="ajax上传文件" />
        </form>
    
    
    </body>
    </html>

    我们可以看见,只需要给要提交的form表单指定一个唯一标识id即可,是不是很方便?

    后台controller接收代码:

    package com.wskj.uploadfile.controller;
    
    import java.io.File;
    import java.io.IOException;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    
    @Controller
    @RequestMapping("/upload")
    public class AjaxController {
    
        @RequestMapping(value="/demo1", method=RequestMethod.GET)
        public String demo1(){
            return "upload/demo1";
        }
        
        @RequestMapping(value="/demo1", method=RequestMethod.POST)
        @ResponseBody
        public boolean demo1(String fileName, MultipartFile myfile, HttpServletRequest request) throws IllegalStateException, IOException{
            
            String path = request.getServletContext().getRealPath("files");
            path += "/" + myfile.getOriginalFilename();
            File file = new File(path);
            myfile.transferTo(file);
            
            System.out.println(fileName+" - 上传成功");
            
            return true;
        }
        
    }

    另外还可以使用jquery.form.js实现ajax的上传:

    前段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>Insert title here</title>
    <script type="text/javascript" src="<%= request.getContextPath()%>/static/jquery-1.10.2.js"></script>
    <script type="text/javascript" src="<%= request.getContextPath()%>/static/jquery.form.js"></script>
    <script type="text/javascript">
    
    $(function(){
    
        $("#btnupload").click(function(){
    
            var url ="<%= request.getContextPath()%>/upload/demo2";
            
            $("#form1").ajaxSubmit({  
                type:'post',  
                url:url,  
                clearForm:true,//清空所有表单元素的值
                resetForm:true,//重置所有表单元素的值
                success:function(data){  
                    alert(data);  
                },  
                error:function(XmlHttpRequest,textStatus,errorThrown){  
                    alert("上传失败了");
                }  
            });  
            
        });
    });
    
    </script>
    
    </head>
    <body>
    
        <h1>使用jquery.form.js实现ajax文件上传</h1>
        <h3>对浏览器没有限制,尽情使用吧骚年们...</h3>
    
        <form id="form1">
            文件名:<input type="text" name="fileName" value="我的头像" />
            文件:<input type="file" name="myfile" />
            <input id="btnupload" type="button" value="ajax上传文件" />
        </form>
    
    
    </body>
    </html>

    后台controller接收代码:

    package com.wskj.uploadfile.controller;
    
    import java.io.File;
    import java.io.IOException;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    
    @Controller
    @RequestMapping("/upload")
    public class AjaxController {
    
       
        
        
        
        @RequestMapping(value="/demo2", method=RequestMethod.GET)
        public String demo2(){
            return "upload/demo2";
        }
        
        @RequestMapping(value="/demo2", method=RequestMethod.POST)
        @ResponseBody
        public boolean demo2(String fileName, MultipartFile myfile, HttpServletRequest request) throws IllegalStateException, IOException{
            
            String path = request.getServletContext().getRealPath("files");
            path += "/" + myfile.getOriginalFilename();
            File file = new File(path);
            myfile.transferTo(file);
            
            System.out.println(fileName+" - 上传成功");
            
            return true;
        }
        
        
    }

    当然,使用这两种方法也必须在spring中配置文件上传解析器,这个是上传二进制文件的前提。

  • 相关阅读:
    webpack 中级配置
    webpack4学习笔记
    window搭建go环境
    谈谈你对laravel的契约,容器,服务提供者,facades的理解以及他们的关系是什么
    php开发微信公众号踩坑
    腾讯云搭建git服务器
    linux的常用命令
    egg项目部署
    axios的使用记录以及实现上传图片
    SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known
  • 原文地址:https://www.cnblogs.com/fengwenzhee/p/7273197.html
Copyright © 2020-2023  润新知