SpringMVC之文件上传/下载

来源:互联网 发布:安吉汽车物流知乎 编辑:程序博客网 时间:2024/05/04 09:34

学习一个框架少不了学习文件上传和下载,原理来说上传和下载都是基本二进制流的转换,所以搞清楚了这一点就很容易理解上传和下载了


在使用springMVC进行系统实现时,springMVC默认的解析器里面是没有加入对文件上传的解析的,这可以方便我们实现自己的文件上传。但如果你想使用springMVC对文件上传的解析器来处理文件上传的时候就需要在spring的applicationContext里面加上springMVC提供的MultipartResolver的申明。这样之后,客户端每次进行请求的时候,springMVC都会检查request里面是否包含多媒体信息,如果包含了就会使用MultipartResolver进行解析,springMVC会使用一个支持文件处理的MultipartHttpServletRequest来包裹当前的HttpServletRequest,然后使用MultipartHttpServletRequest就可以对文件进行处理了。


一.文件上传


1.引入依赖包

文件上传需要额外引入包分别是

  1. commons-fileupload-1.3.1.jar
  2. commons-io-2.4.jar

2.配置jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@taglib prefix="sf" uri="http://www.springframework.org/tags/form" %><html><head>    <meta charset="utf-8">    <title>用户登录</title></head><body>    <%--文件上传的话需要enctype="multipart/form-data"--%>    <sf:form modelAttribute="user" method="post" enctype="multipart/form-data">        用户名:<sf:input path="username"/><sf:errors path="username"/>        <br>        密码:<sf:input path="password"/><sf:errors path="password"/>        <br>        昵称:<sf:input path="nickname"/><sf:errors path="nickname"/>        <br>        <%--这里设置文件上传--%>        文件:<input type="file" name="file">        <input type="submit" value="提交">    </sf:form></body></html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

3.配置相应的控制器

@RequestMapping(value = "/login",method = RequestMethod.POST)    public String login(@Validated User user, BindingResult br, Model model,@RequestParam("file") MultipartFile file){        if (br.hasErrors()){            return "user/login";        }        //分别获取的是变量名file---文件类型---文件名        System.out.println(file.getName()+"---"+file.getContentType()+"---"+file.getOriginalFilename());        try {            if (!file.isEmpty()){            //使用StreamsAPI方式拷贝文件                Streams.copy(file.getInputStream(),new FileOutputStream("E:/temp/"+file.getOriginalFilename()),true);            }        } catch (IOException e) {            System.out.println("文件上传失败");            e.printStackTrace();        }        System.out.println(user.toString());        return "user/login";    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

至此单个文件上传完成.

4.多文件上传

多文件上传很简单,只需要把参数改为数组就可以了

    @RequestMapping(value = "/login",method = RequestMethod.POST)    public String login(@Validated User user, BindingResult br, Model model,@RequestParam("file") MultipartFile[] file){        if (br.hasErrors()){            return "user/login";        }        //这里对文件进行遍历        for (MultipartFile mul:file){        //分别获取的是变量名file---文件类型---文件名            System.out.println(mul.getName()+"---"+mul.getContentType()+"---"+mul.getOriginalFilename());            try {                if (!mul.isEmpty()){                    Streams.copy(mul.getInputStream(),new FileOutputStream("E:/temp/"+mul.getOriginalFilename()),true);                }            } catch (IOException e) {                System.out.println("文件上传失败");                e.printStackTrace();            }        }        System.out.println(user.toString());        return "user/login";    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

二.文件下载


下载需要把文件转换成二进制流,然后让客户端读取这个二进制流写入到本机,这样就实现了下载功能.那么现在就要想两个问题:1.怎么把文件写成二进制流? 2.怎么把让客户端相应,开始下载?

答案;

  1. 写成二进制流可以用之前导入的上传组件提供的方法:FileUtils.readFileToByteArray(file)
  2. 让浏览器响应,则需要设置相应的httpHeader了,并且利用spring提供的ResponseEntity把返回值设置为header和响应内容

1.创建控制器代码

            @RequestMapping(value = "/download",produces = "application/octet-stream;charset=UTF-8")            public ResponseEntity<byte[]> download() throws IOException {//                指定文件,必须是绝对路径            File file = new File("E:/temp/me-bg.jpg");//                下载浏览器响应的那个文件名            String dfileName = "1.jpg";//                下面开始设置HttpHeaders,使得浏览器响应下载            HttpHeaders headers = new HttpHeaders();//                设置响应方式            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);//                设置响应文件            headers.setContentDispositionFormData("attachment", dfileName);//                把文件以二进制形式写回            return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.测试下载

访问指定的控制器就能触发下载了

这里写图片描述

3.补充

有时候下载下来的文件会出现被压缩现象,也就是之前的格式都不存在了.解决办法为配置SpringMVC的messageConverter如下:

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">      <property name="messageConverters">          <list>              <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>          </list>      </property>  </bean>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在SpringBoot中和fastjson一起使用可以如下:

本质上和xml配置是一样的,注入的时候有些转换器都有默认处理类型,所以没必要再次配置

 @Bean    public HttpMessageConverters customConverters() {        //fastjson处理消息转换        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();        FastJsonConfig fastJsonConfig = new FastJsonConfig();        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue);        /*          List<MediaType> fastMediaTypes = new ArrayList<>();          fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);          fastConverter.setSupportedMediaTypes(fastMediaTypes);        */        fastConverter.setFastJsonConfig(fastJsonConfig);        //文件下载使用ByteArrayHttpMessageConverter处理        ByteArrayHttpMessageConverter byteArrayHttpMessageConverter = new ByteArrayHttpMessageConverter();        byteArrayHttpMessageConverter.setDefaultCharset(Charset.forName("UTF-8"));        /*         //ByteArrayHttpMessageConverter默认处理请求类型就是APPLICATION_OCTET_STREAM         List<MediaType> byteMediaTypes = new ArrayList<>();         byteMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);         byteArrayHttpMessageConverter.setSupportedMediaTypes(byteMediaTypes);         */        List<HttpMessageConverter<?>> converters = new ArrayList<>();        converters.add(fastConverter);        converters.add(byteArrayHttpMessageConverter);        return new HttpMessageConverters(converters);    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

另外关于文件名乱码,可以使用URLEncoder转换下即可解决

String filename = URLEncoder.encode(file.getName(),"UTF-8");
  • 1
  • 1

项目示例可以参考:
SSM框架整合: https://github.com/nl101531/JavaWEB

(function () {('pre.prettyprint code').each(function () { var lines = (this).text().split(\n).length;varnumbering = $('
    ').addClass('pre-numbering').hide(); (this).addClass(hasnumbering).parent().append(numbering); for (i = 1; i
    0 0
    原创粉丝点击