SpringMVC==文件的上传和下载

SpringMVC:文件上传及下载

文件上传是项目开发中最常见的功能之一,SringMVC 可以很好地支持文件的上传,但是springmvc上下文中默认没有装配MultipartReseolver,因此默认情况下其不能处理文件上传工作。 如果想使用Springmvc的文件上传功能,则需要在上下文中配置MutilpartResovler。

准备工作

前端表单要求: 为了能上传文件,必须将表达的method设置成post , 并将entcype设置为 multipart/form-data 。 只有这样的情况下 , 浏览器才会把用户的选择的文件已二进制的数据发送给服务器。

对表单中的enctype 属性做个详细的说明:
丶application/x-www=form-urlencoded : 默认方式,只处理表单域中的vale属性值,采用这种编码方式的表单会将表单域中的值处理成url 编码方式。

丶multipart/form-data : 这种编码方式会二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。
丶text/plain:除了把空格转换为 “+” 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。

<form action="" enctype="multipart/form-data" method="post">
    <input type="file" name="file"/>
    <input type="submit">
</form>

一旦设置了enctype为multipart/form-data ,浏览器即会采用二进制的方式处理表单数据,而对于上传的处理则涉及在服务器端解析原始的http响应。在2003年,apche Sofatware Foundation发布了开源的Commons FileUploda组件,其很快成为 Servlet/sp 程序上传文件的最佳选择。

Servlet3.0规范已经提供方法来 处理文件上传,但这种上传需要在Sevlet中完成。而springMVC则提供了更简单的封装。

Spring mvc 为为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的的。Spring mvcApache Commons FileUpload技术实现了一个MultipartResolver实现类:CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。
在springmvc-servlet.xml进行配置文件如下:

**注意!!!**这个bena的id必须为:multipartResolver , 否则上传文件会报400的错误!在这里栽过坑,教训!

> <!--文件上传配置-->
>     <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
>         <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
>         <property name="defaultEncoding" value="utf-8"/>
>         <!-- 上传文件大小上限,单位为字节(10485760=10M) -->
>         <property name="maxUploadSize" value="10485760"/>
>         <property name="maxInMemorySize" value="40960"/>
>     </bean>

除此之外,我们还需要导入文件上传的jar包,commons-fileupload , Maven会自动帮我们导入他的依赖包 commons-io包;

<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.3.3</version>
</dependency>

我们会使用它的实现类 CommonsMultipartFile , 常用方法

String getOriginalFilename():获取上传文件的原名
InputStream getInputStream():获取文件流
void transferTo(File dest):将上传文件保存到一个目录文件中
我们去实际测试一下

方式一:采用流的方式上传文件

前端

<form action="/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="file"/>
    <input type="submit" value="upload">
</form>

Controller

必须加上 @RequestParam , 否则也会报错!作用是用来实现封装!

 @RequestMapping("/upload")

    public String upload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
        //1.获得文件名
        request.setCharacterEncoding("utf-8");
        String filename = file.getOriginalFilename();
        if ("".equals(filename)){
            return "文件不存在";
        }
        //2.上传文件保存路径
        String path = request.getServletContext().getRealPath("/upload");
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        //3.上传文件
        InputStream is = file.getInputStream();
        FileOutputStream os = new FileOutputStream(new File(realPath, filename));

        int len = 0;
        byte[] buffer =  new byte[1024];

        while ((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }

        //4.关闭流
        os.close();
        is.close();
        return "/successful";
    }

运行结果:
在这里插入图片描述
点击选择文件
在这里插入图片描述
选择一个文件,点击提交:
在这里插入图片描述
ok已经上传成功

实现上传的另一种方式:

  //文件上传:CommonsMultipartFile
    @RequestMapping(value = "/upload2")
    @ResponseBody
    public String upload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {

        //上传文件保存路径
        String path = request.getServletContext().getRealPath("/upload");
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }

        //transferTo:将文件写入到磁盘,参数就是一个文件
        file.transferTo(new File(realPath+"/"+file.getOriginalFilename()));

        return "上传完毕";
    }

文件的下载:
在Controller层加入以下代码:

@RequestMapping(value = "/download")
    public String download(HttpServletResponse response) throws IOException {

        //要下载的图片路径:,服务器有没有强,一般下载都有自己公司的图床,地址;
        String path = "C:/Users/Administrator/Desktop";
        String filename = "bz.jpg";

        //设置响应头信息;【固定的不用记,保存即可】
        response.reset(); //让页面不缓存
        response.setCharacterEncoding("UTF-8");
        response.setContentType("multipart/form-data");//二进制流传输数据
        response.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(filename,"UTF-8"));

        File file = new File(path,filename);

        //输入流
        FileInputStream input = new FileInputStream(file);
        //输出流
        ServletOutputStream out = response.getOutputStream();

        //执行操作
        int len = 0;
        byte[] buffer = new byte[1024];

        while ((len = input.read(buffer))!=-1){
            out.write(buffer,0,len);
            out.flush();
        }

        out.close();
        input.close();

        return null;

    }

indedx.jsp中插入:

<p><a href="${pageContext.request.contextPath}/download">下载图片</a></p>

看下运行结果:
在这里插入图片描述
ok完美。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值