微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SpringMVC之文件上传

SpringMVC之文件上传

1. 实现文件上传的三个条件

  1. 文件上传项input类型为 file
  2. 表单必须是通过 post 提交
  3. 表单必须是enctype=“multipart/form-data” ,enctype="multipart/form-data(表示用附件的方式发送表单),否则认就把文件名传递了提交时请求主体发生改变
<form action="${pageContext.request.contextpath}/test01" method="post" 
    enctype="multipart/form-data">
      名称:<input type="text" name="name"><br>
      文件:<input type="file" name="file"><br>
      <input type="submit" value="提交"><br>
 </form>

2. 配置

  1. 想要实现文件上传,首先需要导入响应的 jar 包,具体需要用的是fileupload和io
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>      
    <version>1.2.2</version>
</dependency>
<dependency>  
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>
  1. 在导入 jar 包之后,我们还需要对上传文件时用到的工具类org.springframework.web.multipart.commons.CommonsMultipartResolver类进行相关配置。
<!-- 使用Spring的commonsMultipartResovler配置MultipartResovler用于文件上传  -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	<!--上传文件总大小, 单位为 字节-->
	<property name="maxUploadSize" value="5242800"/>
	<!--上传单个文件的大小, 单位为 字节-->
	<property name="maxUploadSizePerFile" value="5242800"/>
	<!-- 设置请求的编码格式, 认为iso-8859-1 -->
	<property name="defaultEncoding" value="utf-8"/>
	<!-- 设置上传文件的临时路径 -->
	<property name="uploadTempDir" value="upload/temp"/>
</bean>

在配置过程中需要给类的一些属性赋值,上述只是一部分属性

3. multipartfile对象

在配置完之后我们就要编写文件上传代码了,SpringMVC 将上传文件时将文件的相关信息以及操作封装到了 multipartfile 对象中,因此,只需要使用 multipartfile 类型声明模型类的一个属性即可对被上传文件进行操作。

multipartfile 接口的相关方法如下:

  1. byte[] getBytes() :以字节数组的形式返回文件内容
  2. String getContentType() :返回文件内容类型。
  3. InputStream getInputStream() :返回一个InputStream,从中读取文件内容
  4. String getName() :返回请求参数的名称
  5. String getoriginalFilename() :返回上传文件文件名。
  6. long getSize() :返回文件的大小,单位为字节。
  7. boolean isEmpty() :判断被上传文件是否为空。
  8. void transferTo(File destination) :将上传文件保存到目标目录下。

4. 实现单文件上传

  • 创建前台页面选择文件上传
    <form action="${ pageContext.request.contextpath }/upload/singlefile" method="post" enctype="multipart/form-data">
    	选择文件:<input type="file" name="myfile"><br>
    	文件描述:<textarea rows="3" name="description"></textarea><br>
    	<input type="submit" value="提交">
    </form>
    
  • 编写处理上传文件的控制器
    @RequestMapping(value = "test09", method = RequestMethod.POST)
    @ResponseBody //告知 SpringMVC框架 不进行视图跳转,直接进行数据响应
    public void test09(@RequestParam("myfiles") multipartfile multipartfile, HttpServletRequest request) throws IOException {
        // 获取文件上传到具体文件夹的绝对路径
        String realpath = request.getSession().getServletContext().getRealPath("upload");
    	// 获取上传文件名
    	String fileName = multipartfile.getoriginalFilename();
    	// 根据路径构建文件对象
    	// 在构建过程中一定要注意路径问题,最好写成绝对路径
    	File uploadFile = new File(realpath, fileName);
    	// 判断指定文件夹uploadfiles是否存在,不存在就创建
    	if (!uploadFile.exists()) {
    		uploadFile.mkdirs();
    	}
    	// 上传文件
    	multipartfile.transferTo(uploadFile);
    }
    

5. 多文件上传

文件上传和单文件上传区别不大,只是多了一个循环上传文件的过程。

6. 文件下载

文件下载的实现有两种方式,一种是通过超链接实现下载,另一种是通过程序编码方式实现下载。前者虽然实现简单,但暴露了文件的真实位置,而且文件需要放在 web 程序的目录下才能下载。后者能够增加安全访问控制,还可以从任意位置提供下载数据,可以将文件存放web程序目录以外,也可以将文件存放在数据库中。

通过程序编码实现下载需要设置两个响应报头:

  1. Content-Type :告诉浏览器其输出内容不是普通文本文件或者HTML文件,而是一个保存到本地的文件,需要设置该报头的值为application/x-msdownload。在不知道文件的类型型时,也可以设置值为application/octet-stream,该属性值表示任意的字节流
  2. Content-disposition :告诉浏览器不直接处理相应实体内容,由用户选择将相应的实体内容保存到一个文件中,需要设置值为attachment;filename=xxx,指定接收程序处理数据内容的方式。在HTTP应用中,attachment是标准的方式,后面指定的filename参数表示保存文件名称,对于中文名称,需要通过编码转换,否则会出现乱码。
    @RequestMapping(value = "test11")
    public void test11(String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取下载的文件路径
        String realpath = request.getSession().getServletContext().getRealPath("upload");
        // 设置下载文件时的响应报头
        response.setHeader("Content-Type", "application/x-msdownload");
        response.setHeader("Content-disposition", "attachment;filename=" + toUTF8String(fileName));
        // 获取文件输入流
        FileInputStream in = new FileInputStream(new File(realpath, fileName));
        // 获得响应对象的输出流,用于向客户端输出二进制数据
        ServletoutputStream out = response.getoutputStream();
        out.flush();

        int aRead = 0;
        byte[] b = new byte[1024];
        // 写到响应输出流
        while ((aRead = in.read(b)) != -1 && in != null) {
            out.write(b, 0, aRead);
        }
        out.flush();
        // 关闭IO对象
        in.close();
        out.close();
    }


    /**
     * 下载时保存中文文件名的字符编码转换方法
     */
    public String toUTF8String(String str) {
        StringBuffer sb = new StringBuffer();
        int len = str.length();
        for (int i = 0; i < len; i++) {
            // 取出字符串中的每个字符
            char c = str.charat(i);
            // Unicode码值为0-255时,不作处理
            if (c >= 0 && c <= 255) {
                sb.append(c);
            } else {
                // 转换成utf-8编码
                byte[] b;
                try {
                    b = Character.toString(c).getBytes("UTF-8");
                } catch (UnsupportedEncodingException e) {
                    // Todo: handle exception
                    e.printstacktrace();
                    b = null;
                }
                // 转换为%HH的字符串形式
                for (int j = 0; j < b.length; j++) {
                    int k = b[j];
                    if (k < 0) {
                        k &= 255;
                    }
                    sb.append("%" + Integer.toHexString(k).toupperCase());
                }
            }
        }
        return sb.toString();
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐