查看: 757|回复: 0

[Java学习] SpringMVC学习记录(四)--文件上传与下载

发表于 2018-4-16 13:53:12
本帖最后由 半夏花开 于 2018-4-16 14:01 编辑

  •   学习一个框架少不了学习文件上传和下载,原理来说上传和下载都是基本二进制流的转换,所以搞清楚了这一点就很容易理解上传和下载了
      在使用springMVC进行系统实现时,springMVC默认的解析器里面是没有加入对文件上传的解析的,这可以方便我们实现自己的文件上传。但如果你想使用springMVC对文件上传的解析器来处理文件上传的时候就需要在spring的applicationContext里面加上springMVC提供的MultipartResolver的申明。这样之后,客户端每次进行请求的时候,springMVC都会检查request里面是否包含多媒体信息,如果包含了就会使用MultipartResolver进行解析,springMVC会使用一个支持文件处理的MultipartHttpServletRequest来包裹当前的HttpServletRequest,然后使用MultipartHttpServletRequest就可以对文件进行处理了。
      一.文件上传
      1.引入依赖包
      文件上传需要额外引入包分别是
      commons-fileupload-1.3.1.jar
      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" %>






      <%--文件上传的话需要enctype="multipart/form-data"--%>
      
      用户名:

      密码:

      昵称:

      <%--这里设置文件上传--%>
      文件:
      


      12345678910111213141516171819202122
      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";
      }12345678910111213141516171819
      至此单个文件上传完成.
      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";
      }123456789101112131415161718192021
      二.文件下载
      下载需要把文件转换成二进制流,然后让客户端读取这个二进制流写入到本机,这样就实现了下载功能.那么现在就要想两个问题:1.怎么把文件写成二进制流? 2.怎么把让客户端相应,开始下载?
      答案;
      写成二进制流可以用之前导入的上传组件提供的方法:FileUtils.readFileToByteArray(file)
      让浏览器响应,则需要设置相应的httpHeader了,并且利用spring提供的ResponseEntity把返回值设置为header和响应内容
      1.创建控制器代码
      @RequestMapping(value = "/download",produces = "application/octet-stream;charset=UTF-8")
      public ResponseEntity 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(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
      }123456789101112131415
      2.测试下载
      访问指定的控制器就能触发下载了


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

      


       1234567
      在SpringBoot中和fastjson一起使用可以如下:
      本质上和xml配置是一样的,注入的时候有些转换器都有默认处理类型,所以没必要再次配置
      @Bean
      public HttpMessageConverters customConverters() {
      //fastjson处理消息转换
      FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
      FastJsonConfig fastJsonConfig = new FastJsonConfig();
      fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue);
      /*
      List 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 byteMediaTypes = new ArrayList<>();
      byteMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
      byteArrayHttpMessageConverter.setSupportedMediaTypes(byteMediaTypes);
      */
      List<httpmessageconverter> converters = new ArrayList<>();</httpmessageconverter
      converters.add(fastConverter);
      converters.add(byteArrayHttpMessageConverter);
      return new HttpMessageConverters(converters);
      }
      123456789101112131415161718192021222324252627282930
      另外关于文件名乱码,可以使用URLEncoder转换下即可解决
      String filename = URLEncoder.encode(file.getName(),"UTF-8");1
      项目示例可以参考:

项目示例可以参考:
SSM框架整合: http://www.makeru.com.cn/                    java学习交流群:587131012




回复

使用道具 举报