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:\java\workspace\spring\springmvc_fileupload_20170401\WebContent\files
            //是 -》 x:\apache tomcat-7\webapps\appName\files
            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:\java\workspace\spring\springmvc_fileupload_20170401\WebContent\files
                    //是 -》 x:\apache tomcat-7\webapps\appName\files
                    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-width: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中配置文件上传解析器,这个是上传二进制文件的前提。

时间: 2024-10-05 04:19:12

spring实现文件上传(图片解析)的相关文章

Strut2 和Spring MVC 文件上传对比

在Java领域中,有两个常用的文件上传项目:一个是Apache组织Jakarta的Common-FileUpload组件 (http://commons.apache.org/proper/commons-fileupload/),另一个是Oreilly组织的COS框架的 (http://www.servlets.com/cos). 1.Struts2的文件上传 Struts2本身并没提供上传的组件,我们可以通过调用上传框架来实现文件的上传,struts2默认是jakarta作为其文件上传的解析

Spring MVC文件上传出现错误:Required MultipartFile parameter &#39;file&#39; is not present

1.配置文件上传的解析器 首先需要在spring mvc的配置文件中(注意是spring mvc的配置文件而不是spring的配置文件:applicationContext.xml)配置: springmvc-config.xml <!-- 文件上传bean--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartReso

Spring的文件上传

Spring在发现包含multipart的请求后,会使用MultipartResolver的实现bean处理文件上传操作,现有采用Servlet3的 org.springframework.web.multipart.support.StandardServletMultipartResolver 和采用commons-fileupload的 org.springframework.web.multipart.commons.CommonsMultipartResolver 处理文件的上传需要重

spring 文件上传 + 图片缩放 + 图片截取(头像功能)

实现图片上传 用户必须能够上传图片,因此需要文件上传的功能.比较常见的文件上传组件有Commons FileUpload,这里我们选择Commons FileUpload. 首先是页面的form表单设置,记住要配method和enctype属性哦!! <form action="upload.do" method="post"            enctype="multipart/form-data">           &l

Spring MVC文件上传和下载

在Spring MVC中有两种实现上传文件的办法,第一种是Servlet3.0以下的版本通过commons-fileupload与commons-io完成的通用上传,第二种是Servlet3.0以上的版本的Spring内置标准上传,不需借助第3方组件.通用上传也兼容Servlet3.0以上的版本 Servlet3.0以下的通过commons-fileupload上传 1.添加上传依赖包 一个是文件上传的jar包,一个是其所依赖的IO包.这两个jar包,均在Spring支持库的org.apache

Excel文件上传,解析,下载(一 文件上传,使用MultipartFile来实现)

文件上传我使用的是jquery的一个插件"ajaxfileupload.js",使用方式详见下面的一种方式,使用file类型的input,同时需要给button绑定事件,这边使用的"ajaxfileupload.js"当中定义的ajax请求,到后台. <div id="fileupload"> <input type="file" id="file" name="file&quo

SpringMVC , Spring , MyBatis 文件上传

学习一下文件上传下载,为图片上传做准备,感觉有一个世纪没玩过上传下载了,边敲代码边记录,请各路大神指教: 参考:http://blog.csdn.net/wjycgl/article/details/55509480 1:jsp页面from表单:这里有两个必须条件.必须是post方式提交.2:必须有enctype属性,enctype="multipart/form-data" 2:maven的pom.xml中引入jar包 <!--文件上传--> <dependency

spring实现文件上传

spring-文件上传 文件上传的回顾 导入文件上传的jar包 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http:

spring mvc文件上传方法

spring mvc上传功能很强大. spring mvc(注解)上传文件的简单例子,这有几个需要注意的地方1.form的enctype="multipart/form-data" 这个是上传文件必须的2.applicationContext.xml中 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolv