【问题标题】:How can I send a PNG of a QR-code in a HTTP response body (with Spark)?如何在 HTTP 响应正文中发送 QR 码的 PNG(使用 Spark)?
【发布时间】:2014-07-28 17:54:18
【问题描述】:

我想生成一个 QR 码图像,将其转换为 PNG 并将其作为 HTTP 响应返回给我的客户端。

为了生成二维码,我使用 ZXing。我已经通过使用FileOutputStream 和MatrixToImageWriter.writeToStream(...) 编写了转换部分。这就像一个魅力。

我目前使用的网络框架是Spark(版本1.1.1)。 handle(...)-方法的返回设置为响应正文。我在这里做错了什么?

使用当前的解决方案,我在使用 Firefox 执行 GET 请求时得到 The image "http://localhost:4567/qrcode" cannot be displayed because it contains errors。

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());
    }
}

【问题讨论】:

  • 你为什么用base64编码byte[]?如果你想返回一个 png,它需要是原始字节。
  • 我发现几个来源暗示 PNG 的编码应该是 Base64(例如mrbool.com/…)。我尝试返回 ByteArrayOutputStream 和 toByteArray(),两者都产生与字符串相同的结果。
  • 你能直接写信回复吗? spark 网站目前有 2.0 的文档,但表明您应该能够调用 response.raw()。
  • 这让我朝着正确的方向前进。 response.raw().getOutputStream() 返回一个 OutputStream,它必须在 MatrixToImageWriter.writeToStream(bitMatrix, "png", outputStream) 调用中使用。 @Brett 如果您想将此作为正确答案,请随意发布。

标签: java http png zxing


【解决方案1】:

刚刚经历了这个。您可以使用以下代码编写任何文件/二进制数据/输出流:

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

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


return res.raw();

【讨论】:

  • 你真的应该刷新和关闭输出流吗?打开它的人应该关闭它。如果情况不同,您能解释一下原因吗?
  • 响应头呢?
  • res.header("Content-Type", "application/download"); res.header("Content-Disposition", "attachment; filename="+fileOutName); 这些是我提供的适合我的目的的标题。请记住,您可以使用文件名来为客户端命名文件,而不是在服务器上命名文件。
【解决方案2】:

使用 response.getRaw 获取应该用于将 PNG 写入的 OutputStream(使用 MatrixToImageWriter)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-14
    • 2018-07-07
    • 2020-06-23
    • 2014-03-17
    • 2018-05-25
    • 2012-01-17
    • 2019-12-22
    相关资源
    最近更新 更多