附件上傳下載,附件下載前端頁面跳轉的坑

附加上傳、下載自己沒有真正在項目中自己寫過,都是直接調用的框架內現成的方法,所以每次遇到項目框架不提供方法時自己心裏發怯,此處記錄一下項目中自己寫的附件上傳,下載方法,以及下載時前段遇到的坑;

附件上傳

這裏提供的是個接口,前段採用異步的方式進行的上傳;

我們項目的接口書寫方式有些奇怪,和經常用的方法不太一樣;

前段用的是layui的附件上傳組件,寫起來比較方便;

    /**
     * 附件上傳  單文件上傳
     * @param request
     * @param response
     * @param
     */
    @RequestMapping(value = "uploadFile", method = RequestMethod.POST)
    public void uploadFile(HttpServletRequest request, HttpServletResponse response){
      {
        Result result = new Result();
        String json = "";
        Claims b = JWTUtil.parseJWT(request.getParameter("token"), ConfigLoader.baseSecurity);
        String accountName = (String) b.get("accountName");
        Accounts account = accountServicesImpl.getEntityBySql("select * from accounts where account_name = '" + accountName + "' and del_flag = 0", null, Accounts.class);
        User user = accountServicesImpl.getUserByAccount(account.getId());
        File file = null;
        try{
//            MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
//            MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            MultipartFile multipartFilefile = multipartRequest.getFile("file");

            String filename = "";
            Long size = 0l;
//            MultipartFile multipartFilefile=null;
//            Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
//            for (Map.Entry<String, MultipartFile> entry : fileMap.entrySet()) {
//                multipartFilefile = entry.getValue();
                filename = multipartFilefile.getOriginalFilename();
                size = multipartFilefile.getSize();
//            }

            // 從數據字典中獲取上傳路徑
            String upconfigPath = "";
            List<CategoryAttributes> leiMuAtt = new ArrayList<CategoryAttributes>();
            leiMuAtt = ConfCache.attributeConfMap.get("Path_Upload");
            if (leiMuAtt != null && leiMuAtt.size() > 0) {
                for (CategoryAttributes tr : leiMuAtt) {
                    CategoryAttributes c = (CategoryAttributes) tr;
                    if (c.getCategoryAttributesName().equals("上傳公共路徑")) {
                        upconfigPath = c.getCategoryAttributesValue();
                    }
                }
            }
//            String downconfigPath = upconfigPath.substring(upconfigPath.lastIndexOf("/") + 1);
            // 從數據字典中獲取下載路徑
//             String downconfigPath = "";
//             List<CategoryAttributes> leiMuAttt=new ArrayList<CategoryAttributes>();
//             leiMuAttt=ConfCache.attributeConfMap.get("Path_Download");
//             if(leiMuAtt!=null && leiMuAttt.size()>0){
//                 for (CategoryAttributes tr : leiMuAttt) {
//                     CategoryAttributes c = (CategoryAttributes)tr;
//                     downconfigPath=c.getCategoryAttributesValue();
//                     break;
//                 }
//             }
            // 獲取日期時間
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String date = sdf.format(new Date());
            SimpleDateFormat sdft = new SimpleDateFormat("HHmmssSSS");
            String timeValue = sdft.format(new Date());
            // 上傳到服務器的路徑(數據字典上傳配置+“/attachment/”附件文件夾+日期)
            String dir = "";

            dir = upconfigPath + "/taskfiles/" + date + "/";
//            downconfigPath = downconfigPath + "/taskfiles";

            File directory = new File(dir);
            // 目錄不存在,創建目錄
            if (!directory.exists()) {
                directory.mkdir();
            }
            // 原文件信息
            System.out.println(filename);

            try {
                filename = java.net.URLDecoder.decode(filename, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            System.out.println(filename);
            String oldfilename = filename.substring(filename.lastIndexOf("\\") + 1);
            String sourcename = oldfilename.substring(0, oldfilename.lastIndexOf(".")); // 文件名
            String ofileType = oldfilename.substring(oldfilename.lastIndexOf(".") + 1); // 文件後綴
            Long ofileSize = size;
            // 新路徑(dir配置路徑+時間戳.格式後綴)
            String newfile = dir + timeValue + "." + ofileType;
            file = new File(newfile);
            Attachment attachment = new Attachment();// 記錄上傳的信息
            try {
                if (!file.exists()) {
//                    Accounts account = (Accounts) ss.getAttribute("login_user");
                    attachment.setFileName(sourcename);
                    attachment.setDir(dir); // 下載時的相對路徑
                    attachment.setFileSize(ofileSize);
                    attachment.setPhysicalName(timeValue + "");
                    attachment.setCreateTime(new Date());
                    attachment.setCreateUserId(account.getId());
                    // attachment.setAttachedTable(attachedTable);
                    attachment.setStatus(0);
                    attachment.setFileType(0);
                    // attachment.setRecordId(recordId);
                    attachment.setExt(ofileType);
                    attachment.setUploadPath(dir + timeValue + "." + ofileType);
                    attachmentServicesImpl.save(attachment);
                }
//                FileUtils.copyFile((File) files.get(0), file);// 上傳 (複製文件)
                FileUtils.copyInputStreamToFile(multipartFilefile.getInputStream(),file);
            } catch (IOException e1) {
                e1.printStackTrace();
                throw new RuntimeException("文件上傳失敗!");
            }
            StringBuffer sb = new StringBuffer();
            sb.append("{");
            sb.append("\"code\":");
            sb.append(0 + ",");
            sb.append("\"msg\":");
            sb.append("\"上傳成功!\",");
            sb.append("\"data\":");
            sb.append(JsonUtil.object2json(attachment));
            sb.append("}");
            json = sb.toString();
        }catch(Exception e){
            StringBuffer sb = new StringBuffer();
            sb.append("{");
            sb.append("\"code\":");
            sb.append(1 + ",");
            sb.append("\"msg\":");
            sb.append("\"上傳失敗!\",");
            sb.append("}");
            json = sb.toString();
        }
        this.print(json,response);
    }

其中的難點在於如何從HttpServletRequest 中獲取到附件信息,也就是MultipartFile,一開始用的是下面的方法

MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
List<MultipartFile> files = multipartRequest.getFiles("files");

但是這個方法會報錯,提示不能直接轉換成MultipartHttpServletRequest ,所以就換成了最上邊的方法轉換,這樣換過之後還是不行,又提示multipartRequest.getFiles("files")內的數量爲0,也就是沒有附件,所以就用以下方法:

MultipartFile multipartFilefile=null;
            Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
            for (Map.Entry<String, MultipartFile> entry : fileMap.entrySet()) {
                multipartFilefile = entry.getValue();
                filename = multipartFilefile.getOriginalFilename();
                size = multipartFilefile.getSize();
            }

上傳路徑是直接到數據字典內取得;

注:上邊兩個是上傳多文件的方法,後期做了修改,代碼中的纔是單文件上傳;

這裏用到了一個工具類org.apache.commons.io包下的FileUtils,裏面有很多操作文件的方法,可以在網上查到,這裏就不列舉了;

這邊從數據字典中獲取的上傳路徑是/u06/upload,所以文件上傳後入庫的路徑也是這個;另外數據庫中還存入和/u06/upload/日期/文件名.houzhui,下載時就直接取用這個字段了,文件上傳成功後,最後上傳到了與我項目workspace同級的/u06/upload文件夾下;

附件下載

先貼上後臺controller代碼:

 /**
     * 附件下載
     * @param request
     * @param response
     * @param
     */
    @RequestMapping(value = "downloadFile")
    public void downloadFile(HttpServletRequest request, HttpServletResponse response, String id){
        Result result = new Result();
        try{
            Base base = new Attachment();
            base.setId(id);
            String ids = request.getParameter("id");
            Attachment attachment = (Attachment) attachmentServicesImpl.getBean(base);
            String fileName = attachment.getFileName() + "." + attachment.getExt();
//            String dir = attachment.getDir();
            String path = attachment.getUploadPath();
            File sourceFile = new File(path);
            if (!sourceFile.exists()) {  throw new Exception("您下載的資源已不存在");  }
            BufferedInputStream in = null;
            ServletOutputStream out = null;
            try {
//              fileName = URLEncoder.encode(fileName, "UTF-8"); //解決下載文件名亂碼
                response.reset();
                response.setCharacterEncoding("UTF-8");
//              response.setContentType("application/octet-stream");
                response.setContentType("application/force-download");
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
                in = new BufferedInputStream(new FileInputStream(sourceFile));
                out = response.getOutputStream();
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = in.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
                throw new Exception(fileName + " 下載出錯,若有問題請與管理員聯繫");
            } finally {
                out.close();
                in.close();
            }
            result.setSuccess(true);
            result.setMessage("下載成功");
        }catch(Exception e){
            e.printStackTrace();
            result.setSuccess(false);
            result.setMessage("下載失敗!"+e.getMessage());
        }
//        this.print(result.toString(),response);
    }

說一說下載時遇到的坑吧,下載時我是通過點擊<a>標籤,然後觸發一個ajax調用後臺下載的,但是這樣頁面沒有提示任何下載提示,也不報錯,但是response 內有文件的內容,在網上查了一下才知道,附件下載是不能用ajax來搞的,好像ajax返回的是字符類型的結果,瀏覽器沒辦法解析response內的附件,所以必須換方法了,看了別人的方法有用window.href.location的,也有用a標籤內使用download 屬性的,我也試了一下這個屬性,下載的不是原文件,是以download 命名的空文件,然後又在href屬性內直接寫後臺映射地址的,導致頁面跳轉了,也沒有附件下載;最後就用了formdata提交的方式請求,這樣頁面也不會跳轉,還能下載到附件了;

粘上前段代碼;

<div class="layui-upload-list">
            <table class="layui-table">
                <thead>
                <tr><th>文件名</th>
                    <th>大小</th>
                    <th>狀態</th>
                    <th>操作</th>
                </tr></thead>
                <tbody id="demoList"></tbody>
            </table>
        </div>
 $("#demoList").append('<tr>' +
                                                    '<td><a href="#">'+data.list[i].fileName+'.'+data.list[i].ext+'</a></td>' +
                                                    '<td>'+((data.list[i].fileSize)/1014).toFixed(1)+'kb</td>' +
                                                    '<td><span style="color: #5FB878;">上傳成功</span></td>' +
                                                    '<td>' +
                                                        '<button class="layui-btn layui-btn-xs demo-reload layui-hide">重傳</button>'+
                                                        '<button class="layui-btn layui-btn-xs layui-btn-danger demo-delete-exist">刪除</button>' +
                                                    '</td>' +
                                                    '<td class="layui-hide">'+data.list[i].id+'</td>' +
                                                    '</tr>')
 $("#demoList").find("a").on('click',function (e) {
                                        var p_tr = $(this).parent().parent();
                                        //刪除附件數組內的附件id
                                        var tds = p_tr.children();
                                        //找到該附件的主鍵
                                        var id = tds.eq(4).text();
                                        var $eleForm = $("<form method='get'></form>");
                                        $eleForm.attr("action","/CenterChainTaskController/downloadFile");
                                        $(document.body).append($eleForm);
                                        $eleForm.append('<input type="text" name="id" value="'+id+'">')
                                        //提交表單,實現下載
                                        $eleForm.submit();
                                    })

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章