赞
踩
zxing是google的一个二维码生成库,使用时需配置依赖:
- implementation("com.google.zxing:core:3.4.1")
- implementation("com.google.zxing:javase:3.4.1")
我们可以通过MultiFormatWriter().encode()方法获取一个matrix对象:
val matrix = MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hint)
这个方法接受5个参数,按照顺序解释如下:
其中,第5个参数需要传入一个HashMap对象:
- private val hint = mapOf(
- // 误差校正等级
- EncodeHintType.ERROR_CORRECTION to ErrorCorrectionLevel.M,
- // 字符集
- EncodeHintType.CHARACTER_SET to "UTF-8",
- // 外边框像素
- EncodeHintType.MARGIN to 5
- )
需要指定三个键,第一个键的值是误差校正等级,在ErrorCorrectionLevel枚举中,有如下选择:
误差校正等级的存在,可以使二维码被遮挡时,仍然能够被正常扫描。一般来说,误差校正等级越大,二维码就越大
第二个键是字符集,一般用UTF-8即可
第三个键是外边框的像素大小
首先我们需要有一个二维码生成的工具类,可以生成将二维码并将二维码输出至一个输出流:
- package com.example.qrcode.util
-
- import com.google.zxing.BarcodeFormat
- import com.google.zxing.EncodeHintType
- import com.google.zxing.MultiFormatWriter
- import com.google.zxing.client.j2se.MatrixToImageWriter
- import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
- import java.io.OutputStream
-
- object QRUtil {
-
- private val width = 400
- private val height = 400
- private val hint = mapOf(
- // 误差校正等级
- EncodeHintType.ERROR_CORRECTION to ErrorCorrectionLevel.M,
- // 字符集
- EncodeHintType.CHARACTER_SET to "UTF-8",
- // 外边框像素
- EncodeHintType.MARGIN to 5
- )
-
- /**
- * 创建二维码并写入到输出流
- * @param content 二维码内容
- * @param outputStream 输出流
- * */
- fun writeCodeIntoStream(content: String, outputStream: OutputStream){
- val matrix = MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hint)
- MatrixToImageWriter.writeToStream(matrix, "png", outputStream)
- }
-
- }
接下来我们需要一个控制器类,提供电脑生成二维码的登录接口,手机扫描二维码使设备登录的接口,和手机扫描二维码后,电脑登陆成功,跳转的接口:
- package com.example.qrcode.controller
-
- import com.example.qrcode.util.QRUtil
- import jakarta.servlet.http.HttpServletRequest
- import jakarta.servlet.http.HttpServletResponse
- import jakarta.servlet.http.HttpSession
- import org.springframework.web.bind.annotation.PathVariable
- import org.springframework.web.bind.annotation.RequestMapping
- import org.springframework.web.bind.annotation.RestController
- import java.net.URL
-
- @RestController
- class QRLoginController {
-
- val idLogin = HashMap<String, Boolean>()
-
- @RequestMapping("/QR/login")
- fun login(request: HttpServletRequest, response: HttpServletResponse, session: HttpSession){
- if (idLogin.containsKey(session.id) && idLogin[session.id] == true){
- response.sendRedirect("/QR/login/down")
- return
- }
- response.setIntHeader("Refresh", 1)
- val strUrl = request.requestURL.toString()
- val url = URL(strUrl)
- val host = url.host
- val pro = url.protocol
- QRUtil.writeCodeIntoStream("$pro://$host/QR/login/${session.id}", response.outputStream)
- }
-
- @RequestMapping("/QR/login/{id}")
- fun loginByID(@PathVariable("id") id: String): String{
- idLogin[id] = true
- return "登录中"
- }
-
- @RequestMapping("/QR/login/down")
- fun loginDown(): String{
- return "登录成功"
- }
-
- }
在/QR/login接口中,我们首先判断当前会话是否已经被人扫了二维码,如果是,则重定向到/QR/login/down接口中;而如果不是,则会通过设置响应头"Refresh"参数,使电脑浏览器端每个一秒刷新一下,并向电脑输出一个二维码,手机扫描这个二维码后,将会前往/QR/login/{id}接口,并通过可变的URL路径,将id传入。
在/QR/login/{id}接口中,将会将传入的id的登录状态设置为真。这样的话,电脑端访问的/QR/login接口就会跳转至/QR/login/down接口
要注意,这里面的实现方式不是正常的实现方式。正常的实现方式应通过前端的脚本语言实现登录状态的刷新。但是因为我们没有前端,所以采用了这种方法
由于手机扫描二维码时,不会指定访问端口,因此需要在application.properties中,配置服务器的端口:
server.port=80
使用浏览器访问http://[你的IP地址]/QR/login,注意,这里不能通过127.0.0.1或localhost访问,因为需要手机和电脑两个设备访问
这时,浏览器会显示一个二维码(CSDN可能不让上传二维码,因此进行了手动打码):
接下来使用手机扫描这个二维码,会发现浏览器成功的跳转到了登录成功的页面:
因此,我们的二维码登录就成功实现了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。