2014-06-07 11 views
6

Ich möchte ein QR-Code-Bild generieren, es in PNG konvertieren und es als HTTP-Antwort an meinen Client zurückgeben.Wie kann ich ein PNG eines QR-Codes in einem HTTP-Antworttext (mit Spark) senden?

Um den QR-Code zu generieren, benutze ich ZXing. Ich habe das Konvertierungsteil bereits getestet, indem ich eine mit MatrixToImageWriter.writeToStream(...) geschrieben habe. Das funktioniert wie ein Zauber.

Das Web-Framework, das ich derzeit verwende, ist Spark (Version 1.1.1). Die Rückgabe der handle(...) -Methode wird als Antworttext festgelegt. Was mache ich hier falsch?

Mit der aktuellen Lösung bekomme ich The image "http://localhost:4567/qrcode" cannot be displayed because it contains errors beim Ausführen der GET-Anfrage mit 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

Warum Sie das byte [] Base64-Codierung werden? Wenn Sie ein PNG zurückgeben wollen, müssen es die rohen Bytes sein. –

+0

Ich habe mehrere Quellen gefunden, die implizieren, dass die Kodierung für PNG Base64 sein soll (zB http://mrbool.com/how-to-convert-image-to-byte-array-and-byte-array-to-image- in-java/25136). Ich habe versucht, sowohl 'ByteArrayOutputStream' als auch' toByteArray() 'zurückzugeben, beide ergeben das gleiche Ergebnis wie die Zeichenkette. –

+0

Können Sie direkt auf die Antwort schreiben? Die Spark-Website hat derzeit doc für 2.0, aber Sie sollten in der Lage sein, response.raw() aufzurufen. –

Antwort

6

Verwenden response.getRaw einen Output zu erhalten, die verwendet werden soll, die PNG (mit MatrixToImageWriter) zu schreiben.

9

Gerade ging das durch. Sie können eine beliebige Datei/Binärdaten/Ausgabestrom schreiben Sie den folgenden Code:

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

Soll der Ausgabestrom wirklich gespült und geschlossen werden? Derjenige, der es geöffnet hat, sollte es schließen. Wenn das anders ist, könnten Sie erklären warum? – Suma