java实现二维码登录功能

本文采用Springboot工程进行开发,使用Google的zxing生成二维码,直接放代码:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.12.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hcx</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-jdbc</name>
    <description>spring-jdbc</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
        <springfox.version>2.9.2</springfox.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
                <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.3.0</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

配置文件:

user:
  qrcode:
    expire-time: 100000
    file-path: C:/Users/Administrator/Desktop/jar
    file-type: PNG
    height: 400
    width: 400

controller代码:

package com.hcx.jdbc.qr;

import java.io.IOException;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.zxing.WriterException;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@RestController
@Slf4j
@Api("二维码服务")
public class QRCodeController {

    @Autowired
    QRCodeService qrCodeService;
    
    @Autowired
    QRCodeConfig qrCodeConfig;
    
    @PostMapping("/generator-qrcode")
    @ApiOperation("生成二维码")
    public String generatorQRCode(){
        String baseUrl = "跳转页面";
        String key = UUID.randomUUID().toString();
        String path = null;
        try {
            path = qrCodeService.generateQRCodeImage(baseUrl,key);
            QRCode qrCode = new QRCode();
            long expireTime = qrCode.getCreateTime() + qrCodeConfig.getExpireTime();
            qrCode.setExpireTime(expireTime);
            QRCodeCache.getInstance().putQRCodeCache(key, qrCode);
            return path;
        } catch (WriterException e) {
            log.info("生成二维码失败:" + e.getMessage());
            return path;
        } catch (IOException e) {
            log.info("生成二维码失败:" + e.getMessage());
            return path;
        }    
    }
    
    @PostMapping("/generator-scan")
    @ApiOperation("扫码二维码")
    public String scanQRCode(String uuid){
        QRCode qrCode = QRCodeCache.getInstance().getQRCodeCache(uuid);
        if(null ==qrCode){
            return "二维码已过期,请刷新获取";
        }
        if(qrCode.isScan()){
            return "二维码扫码过,请刷新获取";
        }
        if(qrCode.getExpireTime() < System.currentTimeMillis()){
            return "二维码已过期,请刷新获取";
        }
        qrCode.setScan(true);
        return "登录页面";
    }
    
    @PostMapping("/generator-hand")
    @ApiOperation("处理二维码")
    public String handQRCode(String uuid,String userName){
        QRCode qrCode = QRCodeCache.getInstance().getQRCodeCache(uuid);
        if(null ==qrCode){
            return "二维码已过期,请刷新获取";
        }

        if(qrCode.getExpireTime() < System.currentTimeMillis()){
            return "二维码已过期,请刷新获取";
        }
        QRCodeCache.getInstance().removeQRCodeCache(uuid);
        return "登录成功返回逻辑处理";
    }
}

service代码:

package com.hcx.jdbc.qr;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

@Service
public class QRCodeService {
    
    @Autowired
    QRCodeConfig qrCodeConfig;
    
    public String generateQRCodeImage(String basePath,String key) throws WriterException, IOException{
        String text = basePath + "/" + key;
        String path = qrCodeConfig.getFilePath() + File.separator + key +"." + qrCodeConfig.getFileType().toLowerCase();
        
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, qrCodeConfig.getWidth(), qrCodeConfig.getHeight());
        Path filePath = FileSystems.getDefault().getPath(path);
        MatrixToImageWriter.writeToPath(bitMatrix, qrCodeConfig.getFileType(), filePath);
        return path;
    }
}

配置类:

package com.hcx.jdbc.qr;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import lombok.Data;

@Configuration
@Data
@ConfigurationProperties(prefix="user.qrcode")
public class QRCodeConfig {

    private int width;
    private int height;
    private long expireTime;
    private String filePath;
    private String fileType;
}

持久代码:

package com.hcx.jdbc.qr;

import java.util.HashMap;
import java.util.Map;

public class QRCodeCache {

    public static Map<String, QRCode> cacheMap = new HashMap<String, QRCode>();
    
    public static QRCodeCache instance = null;
    
    public static QRCodeCache getInstance() {
        if(instance == null) {
            instance = new QRCodeCache();
        }
        return instance;
    }
    
    private QRCodeCache(){
        
    }

    public void putQRCodeCache(String key,QRCode qrCode){
        cacheMap.put(key, qrCode);
    }
    
    public QRCode getQRCodeCache(String key){
        return cacheMap.get(key);
    }
    
    public void removeQRCodeCache(String key){
        cacheMap.remove(key);
    }
    
}

二维码实体:

@Component
@Data
public class QRCode {

    private Long createTime = System.currentTimeMillis();
    
    private Long expireTime;
        
    private boolean isScan = false;
}

 

posted @ 2020-07-31 17:32  奔跑的鹏腾  阅读(1322)  评论(0编辑  收藏  举报