2015-09-03 9 views
7

Ich habe 2 Spring Web-Anwendungen: Application1 und Application2. In Anwendung1 habe ich einen Endpunkt bei "http://application1/getbigcsv", der Streaming verwendet, um eine gigantische 150-MB-CSV-Datei an den Benutzer zurückzusenden, wenn sie diese URL trifft.Wie kann man riesige Datei über Streaming-Rest servieren?

Ich möchte nicht, dass Benutzer Application1 direkt drücken, sondern stattdessen Application2 drücken. Wenn ich die folgende Methode in meinem Controller in Application2 haben

@RequestMapping(value = "/large.csv", method = GET, produces = "text/csv") 
@ResponseStatus(value = HttpStatus.OK) 
public String streamLargeCSV() { 
    // Make an HTTP Request to http://application1/getbigcsv 
    // Return its response 
} 

Meine Sorge ist, die oben nicht tut „Streaming“, während Application1 Streaming tut. Gibt es eine Möglichkeit, dass ich sicherstellen kann, dass die Anwendung2 die gleichen Daten vom Ruhe-Endpunkt der Anwendung1 streamweise zurückliefert? Oder gibt die obige Methode tatsächlich Dinge in einer "Streaming" -Methode zurück, weil Application1 seinen Endpunkt als Streaming bereitstellt?

+0

für Sie meine Antwort Arbeit getan hat? –

Antwort

13

Zunächst einmal: Sie können aber nicht mit dieser Methode Signatur.

Leider haben Sie nicht gezeigt, wie Sie diese CSV-Datei in app1 produzieren, ob dies wirklich Streaming ist. Nehmen wir an, es ist so.

Sie Signatur wird wie folgt aussehen:

@RequestMapping(value = "/large.csv", method = GET, produces = "text/csv") 
@ResponseStatus(value = HttpStatus.OK) 
public void streamLargeCSV(OutputStream out) { 
    // Make an HTTP Request to http://application1/getbigcsv 
    // Return its response 
} 

Jetzt müssen wir zuerst den Eingangsstrom von app1 greifen. Verwenden Sie Apache HttpClient zu get Ihre HttpEntity. Diese Entität verfügt über eine writeTo(OutputStream)-Methode, die Ihren out-Parameter empfängt. Es wird blockiert, bis alle Bytes verbraucht/gestreamt sind. Wenn Sie fertig sind, geben Sie alle HttpClient-Ressourcen frei.

komplette Code:

@RequestMapping(value = "/large.csv", method = GET, produces = "text/csv") 
@ResponseStatus(value = HttpStatus.OK) 
public void streamLargeCSV(OutputStream out) { 
    // Make an HTTP Request to http://application1/getbigcsv 
    CloseableHttpClient httpclient = HttpClients.createDefault(); 
    HttpGet httpGet = new HttpGet("http://application1/getbigcsv"); 
    CloseableHttpResponse response = httpclient.execute(httpGet); 
    try { 
     HttpEntity entity = response.getEntity(); 
     // Return its response 
     entity.writeTo(out); 
    } finally { 
     response.close(); 
    } 
} 

Here ist mein Beispiel aus der Praxis. Starten Sie aus der Lektüre „Interessant zu sagen, was ich vor allem erreicht haben mit diesem:“

+0

Sie können try-with-resources auf CloseableHttpResponse für weniger Standard verwenden. – approxiblue

+0

@approxiblue Das ist wahr. Fühlen Sie sich frei, meinen Code zu Java 7 zu ersetzen. –

0

In java.ws.rs.core Paket von Klassen haben: StreamingOutput und ResponseBuilder.

Nicht sicher, ob es Ihnen helfen wird, aber Sie können versuchen.

Beispiel:

@Produces("application/octet-stream") 
public Response doThings() { 
...  
    StreamingOutput so; 
    try { 
     so = new StreamingOutput() { 
      public void write(OutputStream output) { 
       … 
      } 
     }; 
    } catch (Exception e) { 
     ... 
    } 

    ResponseBuilder response = Response.ok(so); 
    response.header("Content-Type", ... + ";charset=utf-8"); 
    return response.build(); 
} 
+0

Er benutzt Jersey/JAX-WS nicht. –

0

Ihre Methoden ändern Typ ResponseEntity<?> zurückzukehren und zurück, wie folgend:

@GetMapping("/download") 
public ResponseEntity<?> fetchActivities(
     @RequestParam("filename") String filename) { 

    String string = "some large text" 
    InputStream is = new ByteArrayInputStream(string.getBytest()); 

    HttpHeaders headers = new HttpHeaders(); 
    headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=large.txt"); 
    headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE); 
    return ResponseEntity.ok().headers(headers).body(new InputStreamResource(is)); 
} 
Verwandte Themen