码迷,mamicode.com
首页 > 编程语言 > 详细

SpringMVC下实现文件上传与下载及注意项

时间:2018-12-17 14:17:20      阅读:307      评论:0      收藏:0      [点我收藏+]

标签:att   adc   channel   res   java   pre   throws   real   功能   

提示:项目需求,微信小程序、app等渠道通过http请求实现文件下载。

文件下载:

  第一步:对请求URL进行分解,http:XXXX/downloadfile.file?filePathParam=XX&fileName=XXXXX&isFullUrl=true,通常对外暴露的下载地址都是给出要下载的文件名,但由于项目是给第三方渠道的,所以并不需要进行加密,正常情况文件名及相关参数是需要进行加密的。

 1 public static String getFileFullPath(String filePathParam, String fileName, boolean isFullUrl) throws IOException {
 2         String filePath = PropertiesReader.getProperty("XXXX.properties", filePathParam);
 3         if(!isFullUrl) {
 4             filePath = getFullURL(filePath);
 5         } else {
 6             filePath = filePath.replace("/", File.separator).replace("\\\\", File.separator);
 7             filePath = filePath.endsWith(File.separator)?filePath:filePath + File.separator;
 8         }
 9 
10         return filePath + fileName;
11     }

  一般情况下文件路径的前半截都是维护到配置文件中,通过读取配置文件中路径拼接成全路径。注意:对于目录,linux下是正斜杠,比如 /data/zhenwe/....windows下。windows下则是反斜杠c\windows。

  第二步:获取需要下载文件绝对路径后,可以根据需求重新命名文件名,设置编码及请求头的相关设置。

       String encode = "UTF-8";
            //获取文件的绝对路径
            String filePath = CommonUtil.getFileFullPath(filePathParam, fileName, isFullUrl);
            downLoadFile = new File(filePath);
            downLoadFileName = new String(fileName.replaceAll("\\\\","_").getBytes(encode),"iso-8859-1");
            downLoadFileName=downLoadFileName.substring(downLoadFileName.indexOf("/")+1,downLoadFileName.length());
            headers = new HttpHeaders();
            //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码
            headers.setContentDispositionFormData("attachment",downLoadFileName);
            headers.add("Content-Type", "application/octet-stream; charset="+encode);
            headers.setDate((new Date()).toLong());
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            bFile = FileUtils.readFileToByteArray(downLoadFile);

  注意:在IE11通过http请求下载文件时,IE11浏览器无法解析文件名包含"/"的文件,导致下载下来的文件大小是0KB,后来将文件命中的特殊字符去掉之后,才能下载成功。

下面是整个controller代码:

技术分享图片
@Controller
public class FilePdfDownLoandContorller {
    @RequestMapping({"/downloadfile.{ext}"})
    public ResponseEntity<byte[]> downloadfile(@RequestParam String filePathParam, @RequestParam String fileName, @RequestParam boolean isFullUrl, ModelMap modelMap,
                                               HttpServletRequest request, HttpServletResponse response) throws IOException {
        Logger log = LoggerUtil.getLogger();
        log.info(ERRCODE.LOG.START_BUSIN.getLogText(new String[]{"downloadfile 文件下载"}));
        HttpHeaders headers = null;
        File downLoadFile = null;
        String downLoadFileName = "";
        byte[] bFile = null;

        try {
            if(StringUtils.isNotBlank(request.getParameter("validflag")) && request.getParameter("validflag").equals("true")) {
                Mi040DAO e = (Mi040DAO) SpringContextUtil.getBean("mi040DAO");
                Mi040Example filePath = new Mi040Example();
                Mi040Example.Criteria ca = filePath.createCriteria();
                ca.andChannelEqualTo(request.getParameter("appid")).andCenteridEqualTo(request.getParameter("centerid"));
                List list040 = e.selectByExample(filePath);
                Mi701DAO mi701DAO = (Mi701DAO)SpringContextUtil.getBean("mi701Dao");
                Mi701WithBLOBs mi701 = mi701DAO.selectByPrimaryKey(Integer.valueOf(Integer.parseInt(request.getParameter("seqno"))));
                if(mi701 != null) {
                    Mi711DAO mi711DAO = (Mi711DAO)SpringContextUtil.getBean("mi711Dao");
                    Mi711 mi711 = new Mi711();
                    mi711.setSeqno(Integer.valueOf(Integer.parseInt(request.getParameter("seqno"))));
                    mi711.setCenterid(request.getParameter("centerid"));
                    mi711.setClassfication(request.getParameter("classfication"));
                    mi711.setDatecreated(CommonUtil.getSystemDate());
                    mi711.setPid(((Mi040)list040.get(0)).getPid());
                    mi711.setTitle(mi701.getTitle());
                    mi711.setValidflag("1");
                    mi711DAO.insert(mi711);
                }
            }

            String encode = "UTF-8";
            //获取文件的绝对路径
            String filePath = CommonUtil.getFileFullPath(filePathParam, fileName, isFullUrl);
            downLoadFile = new File(filePath);
            downLoadFileName = new String(fileName.replaceAll("\\\\","_").getBytes(encode),"iso-8859-1");
            downLoadFileName=downLoadFileName.substring(downLoadFileName.indexOf("/")+1,downLoadFileName.length());
            headers = new HttpHeaders();
            //设置content-disposition响应头控制浏览器以下载的形式打开文件,中文文件名要使用URLEncoder.encode方法进行编码,否则会出现文件名乱码
            headers.setContentDispositionFormData("attachment",downLoadFileName);
            headers.add("Content-Type", "application/octet-stream; charset="+encode);
            headers.setDate((new Date()).toLong());
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            bFile = FileUtils.readFileToByteArray(downLoadFile);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            log.info(ERRCODE.LOG.END_BUSIN.getLogText(new String[]{"downloadfile 文件下载"}));
        }

        return new ResponseEntity<byte[]>(bFile,headers, HttpStatus.OK);

    }

}
View Code

  以上是整个文件下载的一些个人理解,说下其中碰到的坑:

  1.   在处理使用IE浏览器下载时,除了上述无法解析特殊字符文件外,在解决兼容性问题时,查资料得知,IE对状态码:(HttpStatus.CREATED)201不支持,支持(HttpStatus.OK)200。
  2. 在IE Microsoft Edge版本,下载时发现文件是直接把文件给打开的,这说明兼容性还没有完全做到位,如果有已解决或者知道原因的大佬们还请指导指导!

文件上传:

  在实现上传功能之前要在applicationContext.xml中配置文件上传的一些设置:文件大小、编码、内存中最大值等。

<!--文件上传相关配置-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--默认编码-->
        <property name="defaultEncoding" value="UTF-8"></property>
        <!--文件大小最大值 上传文件大小限制为10M 10*1024*1024-->
        <property name="maxUploadSize" value="10485760"></property>
        <!--内存中的最大值-->
        <property name="maxInMemorySize" value="4096"></property>
    </bean>

  

  关于文件上传在网上随便搜一下应该就有一大堆实例,这里只记录下在完成下载功能后自己的一些扩展。在网上简单的搜了下前台的一个上传界面,代码如下:

 1 <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
 2 <html>
 3 <head>
 4     <title>文件上传</title>
 5 </head>
 6 <body>
 7     <form method="post" enctype="multipart/form-data" action="${pageContext.request.contextPath}/upload/uploadfile.json">
 8         上传用户名:<input type="text" name="username"/>
 9         文件1:<input type="file" name="file1"/>
10         文件2:<input type="file" name="file2"/>
11         <input type="submit" name="btnsubmit" value="上传" />
12     </form>
13 </body>
14 </html>

  文件上传主要是通过spring的集成类CommonsMultipartResolver来获取MultipartFile并通过File实例化后调用transferTo即可,代码如下:

技术分享图片
 1 @Controller
 2 @RequestMapping("/upload")
 3 public class UploadController {
 4     @Autowired
 5     CommonsMultipartResolver multipartResolver;
 6 
 7     @RequestMapping("/uploadfile.{ext}")
 8     public String fileupload(HttpServletRequest request, HttpServletResponse response) {
 9 
10         if (multipartResolver.isMultipart(request)) {
11             MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
12             Iterator<String> iter = multiRequest.getFileNames();
13 
14             while (iter.hasNext()) {
15                 long sTime = System.currentTimeMillis();
16                 MultipartFile file = multiRequest.getFile(iter.next());
17                 if (file != null) {
18                     String myFileName = file.getOriginalFilename();
19                     if (myFileName.trim() != "") {
20                         System.out.println("需要上传文件名:" + myFileName);
21                         String fileName = "demoUpload" + file.getOriginalFilename();
22                         String path = "D:/" + fileName;
23                         //String proPath = request.getSession().getServletContext().getRealPath("/WEB_INF/upload") + fileName;
24 
25                         File localFile = new File(path);
26                         try {
27                             file.transferTo(localFile);
28                         } catch (IOException e) {
29                             e.printStackTrace();
30                         }
31                     }
32                 }
33                 long eTime = System.currentTimeMillis();
34                 System.out.println("文件上传耗时:" + (eTime - sTime));
35             }
36 
37         }
38         return "/helloWorld";
39     }
40 
41 }
View Code

  

  

 

SpringMVC下实现文件上传与下载及注意项

标签:att   adc   channel   res   java   pre   throws   real   功能   

原文地址:https://www.cnblogs.com/chc24w/p/10130323.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!