美文网首页我爱编程DTeam团队日志每周500字
小技巧:二维码的生成和测试

小技巧:二维码的生成和测试

作者: 胡键 | 来源:发表于2018-07-23 19:15 被阅读76次

    在二维码已不是稀奇事物的今天,你的应用中有大概率会有产生二维码的需求。最近因为开始在做以太坊相关的开发,其中就有一个非常俗的需求:用户的钱包地址需要用二维码展示。

    生成

    在Java界,产生二维码用Google的ZXing即可。其本身没啥好说的,因为用起来很简单。在应用中简单封装一下(Groovy代码):

    class QRCodeUtil {
        static void writeToStream(String walletAddress, OutputStream stream) {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(walletAddress, BarcodeFormat.QR_CODE, 500, 500)
            MatrixToImageWriter.writeToStream(bitMatrix, 'png', stream)
        }
    }
    

    这样就可以在Controller中去调用了(Grails Controller):

    def printWallet() {
        String wallet = params.wallet
        if (!wallet) {
            render status: BAD_REQUEST
            return
        }
    
        PipedInputStream inputStream = new PipedInputStream()
        try {
            inputStream.withStream {
                PipedOutputStream outputStream = new PipedOutputStream(inputStream)
                outputStream.withStream {
                    QRCodeUtil.writeToStream(wallet, outputStream)
                }
                render file: inputStream, contentType: 'image/png'
            }
        } catch (Exception e) {
            log.error("Render QR image error: ", e)
            respond([message: '无法生成钱包二维码'], status: INTERNAL_SERVER_ERROR)
        }
    }
    

    请注意,这里面使用了PipedInputStream/PipedOutputStream,因为这样可以直接将两个流对接,更顺畅的完成图片的输出。

    前端使用也很简单,在页面中,直接使用:< img src='地址' >就行了。

    测试

    生成代码其实已经是烂大街了,这里只是用grails代码重新诠释了一下而已。但是关于二维码的测试,好像就没有那么多的例子了。在这里,我将展示一下我们的做法。

    本质上就是利用ZXing的类读出图片里的字符串,下面是我们的测试工具类(Groovy):

    static String readQRCode(byte[] imageBytes) {
        BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(
                new BufferedImageLuminanceSource(ImageIO.read(new ByteArrayInputStream(imageBytes)))))
        Map<DecodeHintType, ?> hints = new HashMap<>()
        hints.put(DecodeHintType.PURE_BARCODE, true)
        Result qrCodeResult = new MultiFormatReader().decode(binaryBitmap, hints)
        return qrCodeResult.getText()
    }
    

    然后,在Grails的functional测试中实现一个端到端的测试(Spock Specification):

    void "能够生成钱包二维码"() {
        setup:
        RestBuilder rest = new RestBuilder()
    
        when:
        String jwt = TestUtils.login(serverPort, 'user', 'user')
        response = rest.get("http://localhost:${serverPort}/地址") {
            header('Authorization', "Bearer ${jwt}")
            accept(byte[].class, 'image/*')
        }
    
        then:
        response.status == 200
        response.headers.getContentType() == MediaType.valueOf('image/png;charset=utf-8')
        TestUtils.readQRCode(response.body) == '……'
    }
    

    基于Grails的RestBuilder可以很方便的完API测试,这里需要注意的就是accept头的设置。如此,关于二维码的测试就完成了。

    附:感谢冯宇同学提供的支持和帮助。

    相关文章

      网友评论

        本文标题:小技巧:二维码的生成和测试

        本文链接:https://www.haomeiwen.com/subject/xkajmftx.html