2012-08-24 13 views
9

Sto tentando di restituire un'immagine in un servizio Web JAX-RS. Sono riuscito a farlo funzionare correttamente restituendo FileInputStream ma preferirei evitare di creare un File per ogni richiesta.Come restituire l'immagine come flusso da JAX-RS?

Sto usando Apache CXF e Jackson (tutti gli altri metodi di risorse producono l'applicazione/json).

codice simile a questo:

@GET 
@Produces("image/png") 
public Response getQrCode(@QueryParam("qrtext") String qrtext) { 

    ByteArrayOutputStream out = QRCode.from(qrtext).to(ImageType.PNG).stream(); 

    return Response.ok(out).build(); 
} 

Purtroppo, questo produce la temuta:

org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor: 376 - Nessun messaggio scrittore corpo è stato trovato per la classe di risposta ByteArrayOutputStream.

Here's un link ad un post simile, ma non menziona il problema "Nessun messaggio corpo scrittore" Io corro in.

Apprezzerei qualsiasi idea su come affrontare questo problema. Grazie!

+0

Perché non restituire lo stream direttamente anziché avvolgerlo in una risposta? –

risposta

8

Penso che sia necessario fornire un InputStream contenente l'immagine nel Response.ok (out) non un OutputStream. (Il tuo framework JAX-RS leggeva i byte da InputStream e li metteva nella risposta, non sarebbe in grado di fare nulla genericamente con un OutputStream)

(So che sei su CXF, ma il documento di Jersey : http://jersey.java.net/nonav/documentation/latest/jax-rs.html#d4e324 e dalla specifica JAX-RS, il framework deve fornire MessageBodyWriter per InputStream.

Modifica: A quanto pare, gli InputStreams sono richiesti, d'oh ... Hai il controllo sulla classe QRCode?

a breve termine, si potrebbe essere in grado di fare:

return Response.ok(out.toByteArray()).build(); 
+0

grazie. la tua risposta è stata di grande aiuto. Response.ok (out.toByteArray()). Build() funziona bene. – Justin

19

Basta usare StreamingOutput wrapper. Per qualche motivo è sconosciuto, ma è FANTASTICO per fornire, beh, l'output in streaming. :-)

+0

Grazie Tatu. Restituire StreamingOutput è preferibile semplicemente restituendo l'array di byte direttamente come entità di risposta? – Justin

+0

Come al solito, "dipende". Se hai già 'byte []', probabilmente non fa differenza. – StaxMan

+6

Generalmente è una cattiva idea usare toByteArray per gli stream poiché questo in pratica metterà l'intero stream in memoria. Quindi se il tuo file è 1GB, avrai bisogno di almeno 1 GB nella JVM. Se più utenti accedono al tuo servizio, ogni utente aggiungerà 1 GB aggiuntivo, che farà cadere il tuo server. Consiglio sempre di usare direttamente gli stream. – apanosa

Problemi correlati