2016-04-27 69 views
2

spring-mvcアプリケーションで1つのhttp getリクエストで複数のファイルをダウンロードしようとしています。複数のファイルをダウンロードするJava Spring

私はファイルを圧縮してこのファイルを送信できると言っていますが、ファイルがアプリケーションから直接アクセスできないため、私の場合は理想的ではありません。ファイルを取得するには、hbaseまたはhadoopのいずれかからファイルをストリームするRESTインターフェイスをクエリする必要があります。

私はファイルをリポジトリにダウンロードし、圧縮してクライアントに送信するのは長すぎます。 (大きなファイルがすでにzipであることを考慮すると、圧縮すると圧縮されません)。

herethereは、multipart-responseを使用して一度に複数のファイルをダウンロードできますが、結果は得られません。ここに私のコードです:

String boundaryTxt = "--AMZ90RFX875LKMFasdf09DDFF3"; 
response.setContentType("multipart/x-mixed-replace;boundary=" + boundaryTxt.substring(2)); 
ServletOutputStream out = response.getOutputStream(); 

// write the first boundary 
out.write(("\r\n"+boundaryTxt+"\r\n").getBytes()); 

String contentType = "Content-type: application/octet-stream\n"; 

for (String s:files){ 
    System.out.println(s); 
    String[] split = s.trim().split("/"); 
    db = split[1]; 
    key = split[2]+"/"+split[3]+"/"+split[4]; 
    filename = split[4]; 

    out.write((contentType + "\r\n").getBytes()); 
    out.write(("\r\nContent-Disposition: attachment; filename=" +filename+"\r\n").getBytes()); 

    InputStream is = null; 
    if (db.equals("hadoop")){ 
     is = HadoopUtils.get(key); 
    } 
    else if (db.equals("hbase")){ 
     is = HbaseUtils.get(key); 
    } 
    else{ 
     System.out.println("Wrong db with name: " + db); 
    } 
    byte[] buffer = new byte[9000]; // max 8kB for http get 
    int data; 
    while((data = is.read(buffer)) != -1) { 
     out.write(buffer, 0, data); 
    } 
    is.close(); 

    // write bndry after data 
    out.write(("\r\n"+boundaryTxt+"\r\n").getBytes()); 
    response.flushBuffer(); 
    } 
// write the ending boundary 
out.write((boundaryTxt + "--\r\n").getBytes()); 
response.flushBuffer(); 
out.close(); 
} 

奇妙な部分は、ナビゲータによって異なる結果になることです。 Chromeでは何も起こりません(コンソールを見てください)、Firefoxでは、各ファイルのダウンロードを求めるプロンプトが表示されましたが、正しいタイプまたは正しい名前(コンソールには何もありません)はありません。

私のコードにバグはありますか?いいえ、何か別の選択肢がありますか?

編集

また、私はこの記事を見ました:Unable to send a multipart/mixed request to spring MVC based REST service

編集2

firefox result

このファイルの内容は、私が欲しいものであるが、なぜできません私は正しい名前を得て、何もダウンロードできないのですか?

+0

JSでダウンロード要求をループすることができ、要求が完了するたびに新しいダウンロードがトリガーされます。私はこれが複数のダウンロードを引き起こすためにハッキングするよりも簡単だと思います。 –

+0

@WeareBorg私はjsの基本知識しか持っていません。 – Whitefret

+0

残念ながら、私はバックエンド開発者であり、JSも知らない。あなたがJavaで望むなら、私はあなたにZIPダウンロード用のコードを与えることができます。 –

答えて

2

これは、あなたがジッパーを経由してダウンロードを行うことができる方法である。

@RequestMapping(value = "/URL/{mode}/{token}") 
    public void downloadZip(HttpServletResponse response, @PathVariable("token") String token, 
          @PathVariable("mode") boolean mode) { 
     response.setContentType("application/octet-stream"); 
     try { 
      Person person = this.personService.getCurrentlyAuthenticatedUser(); 
      List<Integer> integerList = new ArrayList<>(); 
      String[] integerArray = token.split(":"); 
      for (String value : integerArray) { 
       integerList.add(Integer.valueOf(value)); 
      } 
      if (!mode) { 
       String zipPath = this.groupAttachmentsService.downloadAttachmentsAsZip(integerList); 
       File file = new File(zipPath); 
       response.setHeader("Content-Length", String.valueOf(file.length())); 
       response.setHeader("Content-Disposition", "attachment; filename=\"" + person.getFirstName() + ".zip" + "\""); 
       InputStream is = new FileInputStream(file); 
       FileCopyUtils.copy(IOUtils.toByteArray(is), response.getOutputStream()); 
       response.flushBuffer(); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

はレムが知っている、疑いの包み、楽しみを持っている:zipファイルをダウンロードするための

try { 
     List<GroupAttachments> groupAttachmentsList = attachIdList.stream().map(this::getAttachmentObjectOnlyById).collect(Collectors.toList()); // Get list of Attachment objects 
      Person person = this.personService.getCurrentlyAuthenticatedUser(); 
      String zipSavedAt = zipLocation + String.valueOf(new BigInteger(130, random).toString(32)); // File saved location 
      byte[] buffer = new byte[1024]; 
      FileOutputStream fos = new FileOutputStream(zipSavedAt); 
      ZipOutputStream zos = new ZipOutputStream(fos); 

       GroupAttachments attachments = getAttachmentObjectOnlyById(attachIdList.get(0)); 

        for (GroupAttachments groupAttachments : groupAttachmentsList) { 
          Path path = Paths.get(msg + groupAttachments.getGroupId() + "/" + 
            groupAttachments.getFileIdentifier()); // Get the file from server from given path 
          File file = path.toFile(); 
          FileInputStream fis = new FileInputStream(file); 
          zos.putNextEntry(new ZipEntry(groupAttachments.getFileName())); 
          int length; 

          while ((length = fis.read(buffer)) > 0) { 
           zos.write(buffer, 0, length); 
          } 
          zos.closeEntry(); 
          fis.close(); 

        zos.close(); 
        return zipSavedAt; 
      } 
     } catch (Exception ignored) { 
     } 
     return null; 
    } 

コントローラの方法。

更新

ZIPファイル内のバイト配列。

public static byte[] zipBytes(String filename, byte[] input) throws IOException { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    ZipOutputStream zos = new ZipOutputStream(baos); 
    ZipEntry entry = new ZipEntry(filename); 
    entry.setSize(input.length); 
    zos.putNextEntry(entry); 
    zos.write(input); 
    zos.closeEntry(); 
    zos.close(); 
    return baos.toByteArray(); 
} 
関連する問題