使用Spring boot与ZXing集成生成登录二维码并使用Vant显示

文章目录

  • 前言
  • 一、准备工作
  • 二、springboot 后端
    • 1.控制器编写
    • 2.使用ZXing库
    • 3.Spring Boot Controller
  • 三、创建Vue.js前端(基于vant)
    • 1.创建Axios请求实例
    • 2.创建Vue.js前端
  • 四、完整代码
    • 后端
    • 前端
  • 总结


前言

在现代Web应用中,使用二维码作为登录方式变得越来越普遍。本文将介绍如何使用使用Spring boot与ZXing集成生成登录二维码并使用Vant显示,并通过Spring的ApplicationReadyEvent事件在启动时自动打开浏览器展示登录二维码。


一、准备工作

首先,确保项目中已添加ZXing库的依赖。在pom.xml中添加以下依赖:


<dependency>
    <groupId>com.google.zxinggroupId>
    <artifactId>coreartifactId>
    <version>3.4.1version>
dependency>
<dependency>
    <groupId>com.google.zxinggroupId>
    <artifactId>javaseartifactId>
    <version>3.4.1version> 
dependency>

二、springboot 后端

1.控制器编写

在Spring Boot的LoginController类中,通过ApplicationReadyEvent事件在应用启动时打开浏览器展示登录二维码。

@EventListener({ApplicationReadyEvent.class})
public void applicationReadyEvent() {

	// url可以自己定义 本博客演示的 ip是获取计算机的
	//端口是springboot后端的端口
    String url = "http://" + ip + ":8089/#/login";
    Runtime runtime = Runtime.getRuntime();
    try {
        Process process = new ProcessBuilder("cmd", "/c", "start", url).start();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2.使用ZXing库

通过generateQrCode方法使用ZXing库生成二维码图片:

// 使用 ZXing 生成二维码图片
private BufferedImage generateQrCode(String data) throws WriterException {
    int width = 300;
    int height = 300;

    // 设置二维码参数
    Map<EncodeHintType, Object> hints = new HashMap<>();
    hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

    // 生成二维码矩阵
    BitMatrix matrix = new QRCodeWriter().encode(data, BarcodeFormat.QR_CODE, width, height, hints);

    // 将矩阵转换成 BufferedImage
    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, matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
        }
    }

    return image;
}

3.Spring Boot Controller

我们创建了一个Spring Boot Controller,提供了一个接口 /Login/QrCodeImage 用于获取生成的二维码图片的Base64字符串

@GetMapping("QrCodeImage")
public R getQrCodeImage() {
    String url = "http://" + ip + ":8089/#/"; // 替换为你的应用地址

    try {
        // 生成二维码图片
        BufferedImage qrCodeImage = generateQrCode(url);

        // 转换成byte[]
        ByteArrayOutputStream bas = new ByteArrayOutputStream();
        ImageIO.write(qrCodeImage, "png", bas);

        // 转换成Base64格式
        String base64Image = Base64Utils.encodeToString(bas.toByteArray());

        return new R(true, Collections.singletonList(base64Image));
    } catch (IOException | WriterException e) {
        e.printStackTrace();
        return new R(false, "生成二维码图片时出错");
    }
}

三、创建Vue.js前端(基于vant)

1.创建Axios请求实例

// request.js

import axios from "axios";

const getLocalIPAddress = () => {
    const { hostname } = window.location;
    return hostname;
};

const request = axios.create({
    baseURL: `http://${getLocalIPAddress()}:8089/`,
    changeOrigin: true,
});

export default request;

2.创建Vue.js前端

在Vue.js前端页面中显示登录二维码是一个关键的步骤,下面是一个简单的Vue组件示例,用于显示登录二维码并使用Vant组件库进行页面布局:

<template>
  <div>
    <!-- 使用Vant的NavBar组件显示标题 -->
    <van-nav-bar title="登录" />
    
    <!-- 使用Vant的Image组件显示二维码图片 -->
    <van-image :src="qrCodeImage" />
  </div>
</template>

<script>

import request from "@/unilts/request";

export default {
  data() {
    return {
      qrCodeImage: "",
    };
  },
  mounted() {
    this.getImagePreviews();
  },
  methods: {
    async getImagePreviews() {
      await request.get("/Login/QrCodeImage").then((res) => {
        if (res.data.flag) {
          const data = res.data.data;

          // 将对象的属性值转化为数组
          const images = Object.values(data);

          // 将base64字符串转换为图片,并赋值给qrCodeImage
          this.qrCodeImage = images.map(base64Image => {
            return 'data:image/png;base64,' + base64Image;
          });
        }
      }).finally(() => {
        // 可以在此处添加一些最终的操作
      })
    },
  },
};
</script>

在这个Vue组件中,使用了Vant组件库的NavBar组件和Image组件,它们分别用于显示页面标题和二维码图片。在mounted生命周期钩子中调用getImagePreviews方法,该方法通过请求后端接口获取二维码图片的Base64编码,并将其转换为可在前端显示的图片格式。最后,将转换后的图片赋值给qrCodeImage,在页面上显示登录二维码。

确保在Vue项目中正确引入Vant组件库,以便使用van-nav-bar和van-image组件。

四、完整代码

后端

package cn.weizi.main.web;

import cn.weizi.main.pojo.R;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Service
@CrossOrigin
@RestController
@Controller
@RequestMapping("/Login")
public class LoginController {



    @Value("${start.index.ip}")
    private String ip;


    @EventListener({ApplicationReadyEvent.class})
    public void applicationReadyEvent() {
        String url = "http://" + ip + ":8089/#/login";
        Runtime runtime = Runtime.getRuntime();
        try {
            Process process = new ProcessBuilder("cmd", "/c", "start", url).start();
            // ... (处理进程输出或错误)
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    @GetMapping("QrCodeImage")
    public R getQrCodeImage() {
        //String ipAddress = getCurrentIpAddress(request);
        String url = "http://" + ip + ":8089/#/"; // Replace with your application address


        System.out.println(url);
        try {
            // Generate QR code image
            BufferedImage qrCodeImage = generateQrCode(url);

            // Convert BufferedImage to byte[]
            ByteArrayOutputStream bas = new ByteArrayOutputStream();
            ImageIO.write(qrCodeImage, "png", bas);

            // Convert byte[] to Base64
            String base64Image = Base64Utils.encodeToString(bas.toByteArray());

            return new R(true, Collections.singletonList(base64Image));
        } catch (IOException | WriterException e) {
            e.printStackTrace();
            return new R(false, "Error generating QR code image");
        }
    }



    // 使用 ZXing 生成二维码图片
    private BufferedImage generateQrCode(String data) throws WriterException {
        int width = 300;
        int height = 300;

        // 设置二维码参数
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

        // 生成二维码矩阵
        BitMatrix matrix = new QRCodeWriter().encode(data, BarcodeFormat.QR_CODE, width, height, hints);

        // 将矩阵转换成 BufferedImage
        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, matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
            }
        }

        return image;
    }
}

前端

<template>
  <div>
    <van-nav-bar title="登录" />
    <van-image :src="qrCodeImage"  />
  </div>
</template>

<script>

import request from "@/unilts/request";

export default {
  data() {
    return {
      qrCodeImage: "",
    };
  },
  mounted() {
    this.getImagePreviews();
  },
  methods: {

    async getImagePreviews() {

      await request.get("/Login/QrCodeImage").then((res) => {
        if (res.data.flag) {

          const data = res.data.data;

          // 将对象的属性值转化为数组
          const images = Object.values(data);

          // Convert base64 strings to images and open ImagePreview
          this.qrCodeImage = images.map(base64Image => {
            return 'data:image/jpg;base64,' + base64Image;
          });
        }

      }).finally(() => {

      })
    },



  },
};
</script>

总结

通过本文,你学会了如何使用Spring boot与ZXing集成生成登录二维码并使用Vant显示,并在应用启动时自动打开浏览器展示。这种方式为用户提供了便捷的登录方式,提高了用户体验。

你可能感兴趣的:(Java,spring,boot,后端,java)