springboot工程中生成二维码(Java)

2023-10-30

需求

在系统中生成一个二维码,用户保存下来并分享出去,其他人扫描之后跳到我们的一个活动详情页,查看此活动的内容。

需求分析

从以上的需求中,可以提炼出以下几点:

当用户点击生成二维码的时候,我们要拿到用户生成的二维码是关于哪个活动的;

请求来到后台,拿到活动ID,作为我们活动详情页的参数,生成一个url,作为扫描之后的跳转地址,生成二维码;

把生成的二维码,返回给前端,展示给用户;

用户保存二维码,即下载下来。

以上就是全部业务流程,二维码的内容,可以是一段明文,也可以是一个http或https链接,当扫描时会自动访问这个链接。对于大部分的场景,不能说大部分,应该说99%以上的场景都是给二维码的内容设置为一个链接,扫描之后跳到对应的页面再去执行业务

我们重点分析二维码的生成和用户下载二维码。

二维码如何返回给前端?也许很多人会想到,把生成的二维码存到服务器上,再把图片路径返回不就行了?这样当然可以,但是却多了很多不必要的操作:

对于二维码,我们只需要返回给用户即可,并不需要存到我们的服务器上,这没有任何意义,还占用磁盘空间;

我们可以直接将生成的二维码图片,以IO流的方式,通过response响应体直接返回给请求方。第一,不需要落到我们的磁盘,一切操作都在内存中完成,效率比较高;第二,所有生成二维码的请求,都可以访问这里,前端直接拿img标签的src就能访问,你在浏览器直接输入这个路径也能得到一张图片,减少了很多交互和逻辑处理。

再说第四步,我们直接在前端实现,因为前端有一种机制可以将某个img标签的图片下载下来,不需要浪费我们的服务器。

第一步 导入依赖

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

第二步 编写工具类

package com.bqlg.wecom.app.itservice.feign;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 生成二维码的工具类
 */
public class QRCodeUtils {

    /**
     * 生成二维码
     *
     * @param content 二维码的内容
     * @return BitMatrix对象
     */
    public static BitMatrix createCode(String content) {
        //二维码的宽高
        int width = 200;
        int height = 200;

        //其他参数,如字符集编码
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        //容错级别为H
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //白边的宽度,可取0~4
        hints.put(EncodeHintType.MARGIN, 1);

        BitMatrix bitMatrix = null;
        try {
            //生成矩阵,因为我的业务场景传来的是编码之后的URL,所以先解码
            bitMatrix = new MultiFormatWriter().encode(content,
                    BarcodeFormat.QR_CODE, width, height, hints);

            //bitMatrix = deleteWhite(bitMatrix);
        } catch (WriterException e) {
            e.printStackTrace();
        }

        return bitMatrix;
    }

    /**
     *  删除生成的二维码周围的白边,根据审美决定是否删除
     * @param matrix BitMatrix对象
     * @return BitMatrix对象
     * */
    private static BitMatrix deleteWhite(BitMatrix matrix) {
        int[] rec = matrix.getEnclosingRectangle();
        int resWidth = rec[2] + 1;
        int resHeight = rec[3] + 1;

        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
        resMatrix.clear();
        for (int i = 0; i < resWidth; i++) {
            for (int j = 0; j < resHeight; j++) {
                if (matrix.get(i + rec[0], j + rec[1]))
                    resMatrix.set(i, j);
            }
        }
        return resMatrix;
    }
}

第三部 controller层

/**
     *  生成二维码
     * @param type 二维码的类型,为了演示效果,1跳百度的,2是跳CSDN

     * */
    @GetMapping(value = "/create")
    @ApiOperation("生成活动详情二维码")
    public void getCode(int type , HttpServletResponse response) throws IOException {
        // 设置响应流信息
        response.setContentType("image/jpg");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        OutputStream stream = response.getOutputStream();

        //type是1,生成活动详情、报名的二维码,type是2,生成活动签到的二维码
        String content = (type == 1 ? "http://www.baidu.com" : "https://blog.csdn.net/m0_46991147?spm=1000.2115.3001.5343");
        //获取一个二维码图片
        BitMatrix bitMatrix = QRCodeUtils.createCode(content);
        //以流的形式输出到前端
        MatrixToImageWriter.writeToStream(bitMatrix , "jpg" , stream);
    }
    

扫描生成的二维码,就会跳转到百度,如果type给2就会跳转到CSDN首页。

在项目中的实际效果:

用户点击生成二维码,将img标签的src属性指向我们的API接口即可,然后这个图片就可以显示出来了。

第四步 下载二维码

			function downloadImage(imgsrc, name) {//下载图片地址和图片名
                let image = new Image();
                // 解决跨域 Canvas 污染问题
                image.setAttribute("crossOrigin", "anonymous");
                image.onload = function() {
                    let canvas = document.createElement("canvas");
                    canvas.width = image.width;
                    canvas.height = image.height;
                    let context = canvas.getContext("2d");
                    context.drawImage(image, 0, 0, image.width, image.height);
                    let url = canvas.toDataURL("image/jpg"); //得到图片的base64编码数据
                    let a = document.createElement("a"); // 生成一个a元素
                    let event = new MouseEvent("click"); // 创建一个单击事件
                    a.download = name || "photo"; // 设置图片名称
                    a.href = url; // 将生成的URL设置为a.href属性
                    a.dispatchEvent(event); // 触发a的单击事件
                };
                image.src = imgsrc;
            }

imgSrc就是图片的地址,在这里指向我们上面的API,因为我们的API响应的就是一张图片。
name就是下载之后的文件名。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springboot工程中生成二维码(Java) 的相关文章

随机推荐

  • 为什么说Python是普通人编程领域的王者

    点击上方 菜鸟学Python 选择 星标 公众号 超级无敌干货第一时间推给你 Python 自上个世纪诞生 一直过着不温不火的生活 直到近几年 乘着数据科学的东风 从低调的脚本小兵 成为了全能型的战士 同时也被被培训机构狠狠地炒火了一把 然
  • 稀疏数组

    稀疏数组 1 什么是稀疏数组 稀疏数组可以看做是普通数组的压缩 但是这里说的普通数组是值无效数据量远大于有效数据量的数组 下面蓝色的就是普通的二维数组转换成稀疏数组的形式 2 为什么要用稀疏数组 当二维数组中的很多值的默认值为0 因此也记录
  • iOS开发多线程-线程间的通信

    一 简单说明 线程间通信 在1个进程中 线程往往不是孤立存在的 多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任务后 转到另1个线程继续执行任务 线程间通信常用方法 void perfo
  • 05-----检测某个端口是否开放和查看服务器防火墙状态

    1 检测某个端口是否开放 nc vv 192 168 1 117 8890 结果 2 查看服务器防火墙状态 service firewalld status 或者使用下面的命令查看防火墙状态 主要看系统 systemctl status f
  • CCNP学习考试心得(转)

    CCNP学习考试心得 转 more 当计算机屏幕上显示 Congralation时 我不禁长出一口气 心中想 终于考完了 我所说的终于考完是指 我终于完成了ccnp的考试 四个月的学习 对于某些人来说可能太长了 但是要真正掌握ccnp的内容
  • C++学习系列之打印金字塔和倒金字塔

    实例要求 用符号 打印一个金字塔 用符号 打印一个倒金字塔 金字塔代码 include
  • VSCode中开发JavaWeb项目(Maven+Tomcat+热部署)

    1 安装插件 首先需要安装所用到的插件 分别用来支持Java 热部署和Tomcat服务器的插件 在插件市场中搜索Java 第一个就是Extension Pack for Java 内置了6个依赖插件 直接一键安装即可 然后是热部署插件 市场
  • python recvfrom设置超时_如何在python的socket recv方法上设置超时?

    我需要在python的socket recv方法上设置超时 怎么做 仅供参考 如果您选择使用超时 您需要知道如何处理超时 这个SO问题讨论了超时发生时的处理 stackoverflow com questions 16745409 典型的方
  • elementui实现横向时间轴_横向时间轴(进度条)

    1 2 3 4 5 6 7 8 9 10 timeline box 11 width 100 12 height 8rem 13 position relative 14 15 16 timeline container 17 height
  • 2023 年及未来最佳的软件构建工具

    当今世界 加快任务完成速度和尽可能减少人力投入是一切事物都需要关注的问题 软件开发也不例外 无论你在哪个领域 游戏 区块链 还是应用创建 软件开发的竞争都异常激烈 只要能够帮助到你 采用任何手段都无关紧要 而这也正是构建工具的作用 这些工具
  • Linux——I/O复用(2)—— poll和epoll

    poll原型 poll系统调用和select类似 也是在指定时间内轮询一定数量的文件描述符 以 测试其是否有就绪者 int poll struct pollfd fds int nfds int timeout fds struct pol
  • JAVA笔记--异常处理(第一篇)

    目录 一 异常概念 1 什么是异常 2 try与catch关键字 二 try catch finally 1 catch 2 异常处理过程分析 3 finally 三 throw throws与异常规则 1 throw throws 2 异
  • Unity3d 通过json文件使用C#脚本代码生成多个相机

    首先设计一个存储相机类型的json类如下 using UnityEngine using System using System Collections Serializable public class Cameras public in
  • matlab基本粒子群算法实现(四)

    最后在炼数成金那边找到了很好的一篇教程 在这里把它整理一下 做个粒子群算法的收尾 main m I 清空环境 clc clear II 绘制目标函数曲线 figure x y meshgrid 5 0 1 5 5 0 1 5 z x 2 y
  • 阿里巴巴一道笔试题

    其实这是谷歌的一道面试题 给定能随机生成整数1到5的函数 写出能随机生成整数1到7的函数 惭愧 阿里的笔试题做错了 说实话 以前没见过 见过了就把搞懂 阿里题目 给定rand 7 表示能生成1 7的随机数 使用四则运算和循环等控制语句 可以
  • Python基础之循环语句

    Python基础之循环语句 一 循环语句介绍 1 循环语句理解 2 循环语句示意图 二 循环语句的分类 三 循环控制语句 四 while循环 1 while死循环 2 while条件循环 五 break和continue 1 break使用
  • TCP三次握手和四次挥手 详解

    首先了解下TCP报文 16位源端口号 16位的源端口中包含初始化通信的端口 源端口和源IP地址的作用是标识报文的返回地址 16位目的端口号 16位的目的端口域定义传输的目的 这个端口指明报文接收计算机上的应用程序地址接口 32位序号 32位
  • QProcess调用外部程序阻塞等待问题解决

    QProcess调用外部程序阻塞等待问题解决 简介 第一种 第二种 简介 在使用QProcess调用外部程序时 可能会遇到两种场景 1 调用起来之后就不管 直接运行后面的代码 2 调用起来后需要等待外部程序执行完成 在继续运行下面的代码 第
  • jdbc连接数据库获取所有表,表的字段及类型之Oracle

    https blog csdn net hhhliushen article details 105272439 昨天写的这篇jdbc连接数据库获得所有表 表的所有字段及类型对于mysql来说速度还是可以的 但是对于oracle来说 真的是
  • springboot工程中生成二维码(Java)

    需求 在系统中生成一个二维码 用户保存下来并分享出去 其他人扫描之后跳到我们的一个活动详情页 查看此活动的内容 需求分析 从以上的需求中 可以提炼出以下几点 当用户点击生成二维码的时候 我们要拿到用户生成的二维码是关于哪个活动的 请求来到后