2014-06-07 11 views
6

Voglio generare un'immagine di codice QR, convertirla in PNG e restituirla come risposta HTTP al mio cliente.Come posso inviare un PNG di un codice QR in un corpo di risposta HTTP (con Spark)?

Per generare il codice QR uso ZXing. Ho già testato la parte di conversione scrivendo utilizzando FileOutputStream con MatrixToImageWriter.writeToStream(...). Funziona come un fascino.

Il framework Web attualmente in uso è Spark (Versione 1.1.1). Il ritorno del metodo handle(...) è impostato come corpo della risposta. Cosa sto facendo di sbagliato qui?

Con la soluzione corrente ottengo The image "http://localhost:4567/qrcode" cannot be displayed because it contains errors quando eseguo la richiesta GET con Firefox.

import java.io.ByteArrayOutputStream; 
import java.io.OutputStream; 

import static spark.Spark.get; 
import spark.Request; 
import spark.Response; 
import spark.Route; 

import com.google.gson.Gson; 

import com.google.common.io.BaseEncoding; 
import com.google.zxing.BarcodeFormat; 
import com.google.zxing.client.j2se.MatrixToImageWriter; 
import com.google.zxing.common.BitMatrix; 
import com.google.zxing.qrcode.QRCodeWriter; 

public class App { 
    public static void main(String[] args) { 
     get(new Route("/qrcode") { 

      @Override 
      public Object handle(Request request, Response response) { 
       // Test data 
       QrData data = new QrData("test"); 

       // Data is wrapped in JSON 
       String json = new Gson().toJson(data); 

       // Transform JSON to QR-code PNG byte string 
       String qrString = ""; 
       try { 
        qrString = generatePngQrCode(json); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 

       // Set response parameters 
       response.type("image/png"); 
       response.status(200); 

       // Return response body 
       return qrString; 
      } 
     }); 
    } 

    public String generatePngQrCode(String content) throws Exception { 
     ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 

     // ZXing QR-code encoding 
     BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, 400, 400); 

     // Convert to PNG image and write to stream 
     MatrixToImageWriter.writeToStream(bitMatrix, "png", outputStream); 

     // Encode to Base 64 
     return BaseEncoding.base64().encode(outputStream.toByteArray()); 
    } 
} 
+0

Perché si codifica in base64 al byte []? Se si desidera restituire un png, è necessario che siano i byte non elaborati. –

+0

Ho trovato diverse fonti che implicano che la codifica per PNG dovrebbe essere Base64 (ad esempio http://mrbool.com/how-to-convert-image-to-byte-array-and-byte-array-to-image- in-java/25136). Ho provato a restituire 'ByteArrayOutputStream' e' toByteArray() ', entrambi producono lo stesso risultato della stringa. –

+0

Puoi scrivere direttamente alla risposta? Il sito web di scintilla attualmente ha doc per 2.0, ma indica che dovresti essere in grado di chiamare response.raw(). –

risposta

6

Usa response.getRaw per ottenere un OutputStream che dovrebbe essere utilizzato per scrivere il PNG (utilizzando MatrixToImageWriter).

9

Ho appena passato questo. È possibile scrivere qualsiasi file/dati binari/flusso di output utilizzando il seguente codice:

byte[] bytes = Files.readAllBytes(Paths.get(filePath));   
HttpServletResponse raw = res.raw(); 

raw.getOutputStream().write(bytes); 
raw.getOutputStream().flush(); 
raw.getOutputStream().close(); 


return res.raw(); 
+3

Si suppone davvero di svuotare e chiudere il flusso di output? Chi l'ha aperto dovrebbe chiuderla. Se questo è diverso, potresti spiegare perché? – Suma