使用Java实现二维码生成与扫码验证功能

 更新时间:2025年08月19日 09:43:33   作者:火皇405  
在现代软件开发中,二维码被广泛应用于各种场景,例如支付、预约、身份验证等,本篇文章将以 Java 为例,介绍如何实现二维码的生成以及扫码验证的功能,需要的朋友可以参考下

在现代软件开发中,二维码被广泛应用于各种场景,例如支付、预约、身份验证等。本篇文章将以 Java 为例,介绍如何实现二维码的生成以及扫码验证的功能。

项目依赖

在项目中,我们使用了 zxing 库来生成二维码,以下是 Maven 依赖:

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.3.3</version>
</dependency>

请确保将其添加到项目的 pom.xml 文件中。

一、二维码生成

首先,我们编写了一个工具类,用于生成二维码。

代码实现

public static BufferedImage createImage(String charSet, String content, int qrWidth, int qrHeight) {
    Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 设置容错级别
    hints.put(EncodeHintType.CHARACTER_SET, charSet); // 设置字符集
    hints.put(EncodeHintType.MARGIN, 1); // 设置二维码边距
 
    BitMatrix bitMatrix;
    try {
        bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, qrWidth, qrHeight, hints);
    } catch (WriterException e) {
        throw new RuntimeException("生成二维码失败", e);
    }
 
    int width = bitMatrix.getWidth();
    int height = bitMatrix.getHeight();
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 
    for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
            image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
        }
    }
 
    return image;
}

以上代码中,调用 MultiFormatWriter 来生成二维码图像,并设置字符集、容错级别和边距。

二维码生成业务逻辑

接下来,我们整合二维码生成逻辑到具体业务中:

private void generateQrCode(Long reservationId) {
    // 生成签名
    String sign = CreateSignUtil.createSign(vehicleProperties.getCodeUrl(), reservationId);
    System.err.println("生成的签名 = " + sign);
 
    // 构建完整的 URL
    String url = vehicleProperties.getCodeUrl() + reservationId;
    System.err.println("生成的URL: " + url);
 
    // 生成二维码
    BufferedImage bufferedImage = QrCodeUtil.createImage("utf-8", url, 300, 300);
 
    // 上传二维码
    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
        ImageIO.write(bufferedImage, "jpg", outputStream);
        InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
        minioService.uploadFile(CustomConstant.BUCKET_NAME_QRCODE, inputStream, "image/jpg", reservationId, CustomConstant.NUM_100_LONG, "QrCode.jpg", CustomConstant.FILE_TYPE_QRCODE);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

二、扫码验证

生成二维码后,我们可以通过扫码验证来实现数据校验。验证逻辑主要依赖于签名比对。

签名生成方法

public static String createSign(String secretKey, Long subId) {
    String text = secretKey + subId + secretKey;
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] digest = md.digest(text.getBytes(StandardCharsets.UTF_8));
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            sb.append(String.format("%02x", b & 0xff));
        }
        return sb.toString();
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException("MD5 算法不可用", e);
    }
}

该方法通过将 secretKeysubId 拼接后生成签名,用于二维码验证时的参数匹配。

验证接口

通过 Spring Boot 创建一个验证接口:

@GetMapping("/qrcode")
public ResultApi<?> handleQrCode(@RequestParam Long reservationId, @RequestParam String clientSign) {
    // 重新计算签名
    String serverSign = CreateSignUtil.createSign(vehicleProperties.getCodeUrl(), reservationId);
 
    // 比较签名
    if (serverSign.equals(clientSign)) {
        GroundReservationVO.ReservationDetail byId = groundReservationService.getById(reservationId);
        return ResultApi.success("查询成功", byId);
    } else {
        return ResultApi.success("验证失败!参数不匹配。");
    }
}

当客户端扫码后,发送 reservationIdclientSign 到服务端。服务端根据相同的规则生成签名并进行比对,从而验证参数的正确性。

三、总结

通过以上步骤,我们实现了一个完整的二维码生成和验证功能。其中:

  • 二维码生成使用了 zxing 库,并支持自定义内容和大小。
  • 验证功能通过签名算法实现参数的有效性校验,确保了系统的安全性。

到此这篇关于使用Java实现二维码生成与扫码验证功能的文章就介绍到这了,更多相关Java二维码生成与扫码验证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java全面细致讲解final的使用

    Java全面细致讲解final的使用

    关于final关键字,它也是我们一个经常用的关键字,可以修饰在类上、或者修饰在变量、方法上,以此看来定义它的一些不可变性!像我们经常使用的String类中,它便是final来修饰的类,并且它的字符数组也是被final所修饰的。但是一些final的一些细节你真的了解过吗
    2022-05-05
  • Java数据结构之链表实现(单向、双向链表及链表反转)

    Java数据结构之链表实现(单向、双向链表及链表反转)

    这篇文章主要给大家介绍了关于Java数据结构之链表实现的相关资料,其中包括单向链表、双向链表及链表反转的实现代码,需要的朋友可以参考下
    2021-06-06
  • Javaweb使用thymeleaf局部刷新结合Layui插件实现Html分页

    Javaweb使用thymeleaf局部刷新结合Layui插件实现Html分页

    本文主要介绍了Javaweb使用thymeleaf局部刷新结合Layui插件实现Html分页,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • Mybatis SqlSession案例详解

    Mybatis SqlSession案例详解

    这篇文章主要介绍了Mybatis SqlSession详解,本文我们讲了如何创建SqlSession的几个步骤,最后我们获得一个DefaultSqlSession对象,里面包含了执行器Executor和配置对象Configuration,需要的朋友可以参考下
    2023-04-04
  • MybatisPlus多条件 or()的使用问题小结

    MybatisPlus多条件 or()的使用问题小结

    这篇文章主要介绍了MybatisPlus多条件 or()的使用问题小结,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • Spring MVC中使用Controller如何进行重定向

    Spring MVC中使用Controller如何进行重定向

    这篇文章主要介绍了Spring MVC中使用Controller如何进行重定向操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java面试必考之如何在项目中优雅的抛出异常

    Java面试必考之如何在项目中优雅的抛出异常

    这篇文章主要为大家详细介绍了Java中的几种异常关键字和异常类相关知识,本文比较适合刚入坑Java的小白以及准备秋招的大佬阅读,需要的可以收藏一下
    2023-06-06
  • java中Optional的使用详细解析

    java中Optional的使用详细解析

    这篇文章主要介绍了java新特性之Optional的详细解析,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • springboot中使用Hibernate-Validation校验参数详解

    springboot中使用Hibernate-Validation校验参数详解

    这篇文章主要为大家介绍了springboot中使用Hibernate-Validation校验参数详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Java日期工具类操作字符串Date和LocalDate互转

    Java日期工具类操作字符串Date和LocalDate互转

    这篇文章主要介绍了Java日期工具类操作字符串Date和LocalDate互转,文章首先通过需要先引入坐标展开主题的相关内容介绍,需要的朋友可以参一下
    2022-06-06

最新评论