SpringMVC的单文件上传,多文件上传和下载文件(十二)上

一. SpringMVC的文件上传和下载


文件上传和下载功能是非常常用的,如上传用户的头像和上传文档等。 可以结合老蝴蝶以前写的文章Struts2的文件上传功能来结合性学习:Struts2实现单文件上传,多文件上传与下载(十)


SpringMVC在实现上传的时候,主要依赖于 org.springframework.web.multipart.MultipartFile 接口。


其接口定义为:


public abstract interface MultipartFile
  extends InputStreamSource
{
  public abstract String getName();
  
  public abstract String getOriginalFilename();
  
  public abstract String getContentType();
  
  public abstract boolean isEmpty();
  
  public abstract long getSize();
  
  public abstract byte[] getBytes()
    throws IOException;
  
  public abstract InputStream getInputStream()
    throws IOException;
  
  public abstract void transferTo(File paramFile)
    throws IOException, IllegalStateException;
}


其中,主要使用的是 getOriginalFilename()和 transferTo() 方法。 前者是获取 上传文件的名称,后者是进行文件的复制。


MultipartFile 接口的实现类是: org.springframework.web.multipart.commons.CommonsMultipartFile


这个类也与Struts2一样,同样需要依赖于apache 提供的文件上传jar包。


commons-fileupload-1.3.1.jar,commons-io-2.4.jar


SpringMVC的单文件上传,多文件上传和下载文件(十二)上


SpringMVC在上传文件的时候,可以将其放置在方法里面,单独使用,也可以将其与相应的对象类进行关联使用。 通常选用第二种方式。


也同样是简单的User 类。 比以前多添加了一个 image 属性,来进行上传。

所拥有的属性有: (为节省篇福,避免出现像前几章那样长的坏文章形式,老蝴蝶就不贴完整的代码了。抱歉。)


    private Integer id;
    private String name;
    private String sex;
    private Integer age;
    private String descrption;
    
    //有一个上传图片的路径的属性
    
    private String image;


均需要导入 上面那两个jar包。 不要忘记噢


SpringMVC的单文件上传,多文件上传和下载文件(十二)上


二. SpringMVC实现单文件上传,方法内参数形式


二.一 前端界面1 login.jsp ,上传文件


要注意, 提交的方法类型为post, enctype类型为 multipart/form-data


用的是普通的 type=file 框,并没有form:file 标签。


<body>
    <h2>两个蝴蝶飞,文件上传使用</h2>
    <form:form commandName="user" action="login.action"  
    enctype="multipart/form-data" type="post">
        <form:label path="name">姓名:</form:label>
        <form:input path="name"/> <br/><br/>

        <input type="file" name="file"> <br/><br/>

        <form:button>提交</form:button>
    </form:form>
</body>


二.二 前端界面2 list.jsp,展示文件


<body>
    你好,${message} <img src="${pageContext.request.contextPath}${user.image}" width=100 height=100>
</body>


二.三 后端处理, UserAction


    //转到登录的页面
    @RequestMapping(value="toLogin")
    public String toLogin(Model model){
        model.addAttribute("user",new User());
        return "user/login";
    }
    //绑定到user对象。 value="file" 要与form表单的file框的name相同.
    @RequestMapping(value="login") 
    public String login(User user,Model model,HttpServletRequest request,
            @RequestParam(value="file") MultipartFile file){
        System.out.println("输出名称:"+user.getName());
        System.out.println("输出MultipartFile接口中的各个方法的值");
        System.out.println("contentType:"+file.getContentType());
        System.out.println("name:"+file.getName());
        System.out.println("originalFilename:"+file.getOriginalFilename());
        System.out.println("size:"+file.getSize());
        String message="";
        //进行上传文件
        if(!file.isEmpty()){  //不为空,即上传了文件
            //1. 获取服务器的文件
            String path=request.getServletContext().getRealPath("/upload");
            //2. 获取上传的文件的名称
            String fileName=file.getOriginalFilename();
            //3. 实例化构建文件。
            File filePath=new File(path,fileName);
            //4.判断文件,如果父不存在的话,即upload文件夹不存在的话,就创建父级文件夹。
            if(!filePath.getParentFile().exists()){
                filePath.getParentFile().mkdirs(); 
            }
            
            try {
                file.transferTo(new File(path+File.separator+fileName));
                message="文件上传成功";
                //设置上传的路径,这里手动设置
                user.setImage("/upload"+"/"+fileName);
                System.out.println("输出图片路径:"+user.getImage());
            } catch (IllegalStateException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
                message="文件上传失败";
            } catch (IOException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
                message="文件上传失败";
            }
        }else{
            message="没有上传文件";
        }
        model.addAttribute("user",user);
        model.addAttribute("message",message);
        return "user/list";
    }


二.四 springmvc.xml 配置文件中配置文件上传的 CommonsMultipartResolver


在 <mvc:annotation-driven></mvc:annotation-driven> 里面,并没有默认提供关于文件上传的解析器。


需要单独添加


    <mvc:annotation-driven></mvc:annotation-driven>
    <!-- 添加文件上传所用的bean -->
    <bean id="multipartResolver"  
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
        <!-- 上传文件大小上限,单位为字节(10MB) -->
        <property name="maxUploadSize">  
            <value>10000000</value>  
        </property>  
        <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
        <property name="defaultEncoding">
            <value>UTF-8</value>
        </property>
    </bean>


二.五 重启服务器,进行验证


要上传的图片是:


SpringMVC的单文件上传,多文件上传和下载文件(十二)上


进行上传:


SpringMVC的单文件上传,多文件上传和下载文件(十二)上


上传成功,页面跳转展示:


SpringMVC的单文件上传,多文件上传和下载文件(十二)上


控制台打印输出:


SpringMVC的单文件上传,多文件上传和下载文件(十二)上


Tomcat 服务器上,upload 文件夹下有这个图片文件。


SpringMVC的单文件上传,多文件上传和下载文件(十二)上


文件上传成功。 相比较Struts2来说,非常非常简单。


三. SpringMVC实现单文件上传,与对象关联形式


并不是将 MultipartFile 放置在方法里面了,而是放置在User 对象里面。


三.一 User.java 中添加一个MultipartFile类型 的属性。


//定义属性为imageFile
    private MultipartFile imageFile;


要实现setter 和getter的方法。


三.二 前端login.jsp 需要改变一下,将type=file的name改成 imageFile .


<form:form commandName="user" action="login.action"  
    enctype="multipart/form-data" type="post">
        <form:label path="name">姓名:</form:label>
        <form:input path="name"/> <br/><br/>
        
<!--与user 类中的那个属性值对应-->
        <input type="file" name="imageFile"> <br/><br/>
        
        <form:button>提交</form:button>
    </form:form>


list.jsp 保持不变。


三.三 后端 UserAction 需要改变一下,去除多余的输出


//转到登录的页面
    @RequestMapping(value="toLogin")
    public String toLogin(Model model){
        model.addAttribute("user",new User());
        return "user/login";
    }
//绑定到user对象。
    @RequestMapping(value="login") 
    public String login(User user,Model model,HttpServletRequest request){
        
        String message="";
        MultipartFile file=user.getImageFile();
        
        /*后面这些都一样了*/
        //进行上传文件
        if(null!=file&&!file.isEmpty()){  //不为空,即上传了文件
            //1. 获取服务器的文件
            String path=request.getServletContext().getRealPath("/upload");
            //2. 获取上传的文件的名称
            String fileName=file.getOriginalFilename();
            //3. 实例化构建文件。
            File filePath=new File(path,fileName);
            //4.判断文件,如果父不存在的话,即upload文件夹不存在的话,就创建父级文件夹。
            if(!filePath.getParentFile().exists()){
                filePath.getParentFile().mkdirs(); 
            }
            try {
                file.transferTo(new File(path+File.separator+fileName));
                //设置图片的路径。
                user.setImage("/"+"upload"+"/"+fileName);
                message="文件上传成功";
            } catch (IllegalStateException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
                message="文件上传失败";
            } catch (IOException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
                message="文件上传失败";
            }
        }else{
            message="没有上传文件";
        }
        model.addAttribute("user",user);
        model.addAttribute("message",message);
        return "user/list";
    }


三.四 springmvc.xml 的配置与上面的一样,不需要改变


三.五 运行服务器,进行测试


用这张图片进行测试


SpringMVC的单文件上传,多文件上传和下载文件(十二)上


点击提交,运行成功,跳转到list.jsp页面。页面展示:



SpringMVC的单文件上传,多文件上传和下载文件(十二)上


哈哈,这猫,很形象啊。


上一篇:Google Earth Engine——地图对象


下一篇:SpringMVC的单文件上传,多文件上传和下载文件(十二)下