ここにタスクがあります - UI 側 (JavaScript) からのデータに基づいてファイルを生成する必要があります。スキーマは非常に単純です。
UI はサーバーに対して非同期の POST HTTP 要求を作成し、いくつかの JSON データを提供します。
$.ajax({ url: '/reports', type: "POST", data: JSON.stringify({...}), success: function (uuid) { window.location = "/reports/" + uuid; } });
サーバーはリクエストを受け取り、ファイルを生成し、それをファイルシステムに置き、一意の ID を返します。
@RequestMapping(value = "/reports", method = RequestMethod.POST) public String generateReport(ReqData data) throws IOException { final String fileUuid = UUID.randomUUID(); ... //generate a report and return filename ... return fileUuid; }
UI 側は、生成されたファイルの一意の ID を取得し、それを要求します。
success: function (uuid) { window.location = "/reports/" + uuid; }
サーバーは要求されたファイルを出力します。
@RequestMapping(value = "/reports/{uuid}", method = RequestMethod.GET) public ResponseEntity<InputStreamResource> downloadReport(@PathVariable("uuid") String fileUuid) throws IOException { final String resultFileName = fileUuid + ".txt"; final Path resultFile = Paths.get(resultFileName); return ResponseEntity .ok() .header("Content-Disposition", "attachment; filename=\"" + resultFileName + "\"") .contentLength(Files.size(resultFile)) .contentType(MediaType.parseMediaType("text/plain")) .body(new InputStreamResource(Files.newInputStream(resultFile))); }
問題は、このスキーマを複数のサーバーで検討するときに始まります。Server_AとServer_Bの2 つのインスタンスがあり、それらの前にロード バランサーがある場合、上記の両方の要求が同じサーバーに送信されるようにする必要があります。したがって、スティッキー セッションが必要です。http://server_a/reports/123のように指定されたサーバーに絶対パスを提供することは、すべてのサーバーを外界から到達できないようにするため、適切なオプションではありません。
では、生成されたファイルのダウンロードを実装し、スティッキー セッションを回避するには、どのようなオプションを利用できるのでしょうか?