JAVA项目实战-生成二维码和验证码功能

本节将分享java生成二维码和验证码功能,希望能帮助你!

 

package com.sf.vsolution.hb.sfce.util.verifycode;


import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * 验证码生成工具
 */
public class VerifyCodeUtil {

    /**
     * 验证码类型为仅数字,即0~9
     */
    public static final int TYPE_NUM_ONLY = 0;
    /**
     * 验证码类型为仅字母,即大小写字母混合
     */
    public static final int TYPE_LETTER_ONLY = 1;
    /**
     * 验证码类型为数字和大小写字母混合
     */
    public static final int TYPE_ALL_MIXED = 2;

    /**
     * 验证码类型为数字和大写字母混合
     */
    public static final int TYPE_NUM_UPPER = 3;

    /**
     * 验证码类型为数字和小写字母混合
     */
    public static final int TYPE_NUM_LOWER = 4;

    /**
     * 验证码类型为仅大写字母
     */
    public static final int TYPE_UPPER_ONLY = 5;
    /**
     * 验证码类型为仅小写字母
     */
    public static final int TYPE_LOWER_ONLY = 6;


    private VerifyCodeUtil(){}

    /**
     * 生成验证码
     * @param request
     * @param response
     * @throws IOException
     */
    public void getVerifyCodeImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        String verifyCode = generateTextCode(VerifyCodeUtil.TYPE_NUM_LOWER, 4, null);
        response.setContentType("image/jpeg");
        BufferedImage bufferedImage =generateImageCode(verifyCode, 90, 30, 3, true, Color.WHITE, Color.BLACK, null);
        ImageIO.write(bufferedImage, "jpeg", response.getOutputStream());
    }

    /**
     * 生成验证码字符串
     * @param type          验证码类型,参见本类的静态属
     * @param length        验证码长度,要求大于0的整数
     * @param excludeString 需排除的特殊字符(无需排除则为null)
     * @return 验证码字符串
     */
    public static String generateTextCode(int type, int length, String excludeString){
        if(length <= 0){
            return "";
        }

        StringBuffer verifyCode = new StringBuffer();
        int i = 0;
        Random random = new Random();
        switch(type){
            case TYPE_NUM_ONLY:
                while(i < length){
                    int t = random.nextInt(10);
                    //排除特殊字符
                    if(null==excludeString || excludeString.indexOf(t+"")<0) {
                        verifyCode.append(t);
                        i++;
                    }
                }
                break;
            case TYPE_LETTER_ONLY:
                while(i < length){
                    int t = random.nextInt(123);
                    if((t>=97 || (t>=65&&t<=90)) && (null==excludeString||excludeString.indexOf((char)t)<0)){
                        verifyCode.append((char)t);
                        i++;
                    }

                }
                break;
            case TYPE_ALL_MIXED:
                while(i < length){
                    int t = random.nextInt(123);
                    if((t>=97 || (t>=65&&t<=90) || (t>=48&&t<=57)) && (null==excludeString||excludeString.indexOf((char)t)<0)){
                        verifyCode.append((char)t);
                        i++;
                    }
                }
                break;
            case TYPE_NUM_UPPER:
                while(i < length){
                    int t = random.nextInt(91);
                    if((t>=65 || (t>=48&&t<=57)) && (null==excludeString || excludeString.indexOf((char)t)<0)){
                        verifyCode.append((char)t);
                        i++;
                    }
                }
                break;
            case TYPE_NUM_LOWER:
                while(i < length){

                    int t = random.nextInt(123);

                    if((t>=97 || (t>=48&&t<=57)) && (null==excludeString || excludeString.indexOf((char)t)<0)){

                        verifyCode.append((char)t);

                        i++;

                    }

                }

                break;

            case TYPE_UPPER_ONLY:
                while(i < length){
                    int t = random.nextInt(91);
                    if((t >= 65) && (null==excludeString||excludeString.indexOf((char)t)<0)){
                        verifyCode.append((char)t);
                        i++;
                    }
                }

                break;
            case TYPE_LOWER_ONLY:
                while(i < length){
                    int t = random.nextInt(123);
                    if((t>=97) && (null==excludeString||excludeString.indexOf((char)t)<0)){
                        verifyCode.append((char)t);
                        i++;
                    }

                }
                break;
        }
        return verifyCode.toString();
    }



    /**
     * 已有验证码,生成验证码图片
     * @param textCode       文本验证码
     * @param width          图片宽度(注意此宽度若过小,容易造成验证码文本显示不全,如4个字符的文本可使用85到90的宽度)
     * @param height         图片高度
     * @param interLine      图片中干扰线的条数
     * @param randomLocation 每个字符的高低位置是否随机
     * @param backColor      图片颜色,若为null则表示采用随机颜色
     * @param foreColor      字体颜色,若为null则表示采用随机颜色
     * @param lineColor      干扰线颜色,若为null则表示采用随机颜色
     * @return 图片缓存对象
     */

    public static BufferedImage generateImageCode(String textCode, int width, int height, int interLine, boolean randomLocation, Color backColor, Color foreColor, Color lineColor){
        //创建内存图像
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //获取图形上下文
        Graphics graphics = bufferedImage.getGraphics();
        //画背景图
        graphics.setColor(null==backColor ? generateRandomColor() : backColor);
        graphics.fillRect(0, 0, width, height);
        //画干扰线
        Random random = new Random();
        if(interLine > 0){
            int x = 0, y = 0, x1 = width, y1 = 0;
            for(int i=0; i<interLine; i++){
                graphics.setColor(null==lineColor ? generateRandomColor() : lineColor);
                y = random.nextInt(height);
                y1 = random.nextInt(height);
                graphics.drawLine(x, y, x1, y1);
            }

        }
        //字体大小为图片高度的80%
        int fsize = (int)(height * 0.8);
        int fx = height - fsize;
        int fy = fsize;
        //设定字体
        graphics.setFont(new Font("Default", Font.PLAIN, fsize));
        //写验证码字符
        for(int i=0; i<textCode.length(); i++){
            fy = randomLocation ? (int)((Math.random()*0.3+0.6)*height) : fy;
            graphics.setColor(null==foreColor ? generateRandomColor() : foreColor);
            //将验证码字符显示到图象中
            graphics.drawString(textCode.charAt(i)+"", fx, fy);
            fx += fsize * 0.9;
        }
        graphics.dispose();
        return bufferedImage;
    }



    /**
     * 生成随机颜色
     */
    private static Color generateRandomColor() {
        Random random = new Random();
        return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
    }
}

 

 

package com.sf.vsolution.hb.sfce.util.qrcode;

import cn.hutool.extra.qrcode.QrConfig;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

/**
 * @ClassName QrCodeUtil
 * @Description
 * @Author 01374735
 * @Date 2019/7/29
 **/
public class QrCodeUtil {
    private static final Logger LOG = LogManager.getLogger(QrCodeUtil.class);

 

    /**
     * 二维码LOG 位置(默认放在项目中)
     */
    private static final String SFLOG = "/static/img/sflog.png";

    /**
     * 二维码背景图片 位置(默认放在项目中)
     */
    private static final String QRBG = "/static/img/qrbg.png";

    /**
     * 文件导出
     * @param response 相应头
     * @param filePath 二维码图片地址
     */
    public static void exportImg(HttpServletResponse response, String filePath) {
        File file = new File(filePath);
        response.setCharacterEncoding("utf-8");
        //设置响应的内容类型
        response.setContentType("text/plain");
        //设置文件的名称和格式
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Disposition", "attachment;filename=" + file.getName());
        BufferedOutputStream buff = null;
        ServletOutputStream outStr = null;
        try {
            outStr = response.getOutputStream();
            buff = new BufferedOutputStream(outStr);
            buff.write(cn.hutool.core.io.FileUtil.readBytes(filePath));
            buff.flush();
            buff.close();
        } catch (Exception e) {
            e.printStackTrace();
            LOG.error("文件导出异常:", e);
        } finally {
            try {
                buff.close();
            } catch (Exception e) {
                LOG.error("流关闭异常:", e);
            }
            try {
                outStr.close();
            } catch (Exception e) {
                LOG.error("流关闭异常:", e);
            }
        }
    }



    /**
     * 生成二维码地址
     *
     * @param url        二维码跳转链接
     * @param pathFolder 生成地址文件夹
     * @param qrName     二维码名称
     * @return
     */
    public static String generateQrCode(String url, String pathFolder, String qrName) throws IOException {
        String log = QrCodeUtil.class.getResource(SFLOG).getPath();
        String bg = QrCodeUtil.class.getResource(QRBG).getPath();
        QrConfig config = new QrConfig(860, 860);
        //顺丰log
        config.setImg(log);
        // 生成二维码到文件,也可以到流
        File path = new File(pathFolder);
        if (!path.exists()) {
            path.mkdirs();
        }
        String qrFile = pathFolder + System.currentTimeMillis() + ".png";
        cn.hutool.extra.qrcode.QrCodeUtil.generate(url, config, new File(qrFile));

        //设置背景图片
        BufferedImage exImage = ImageIO.read(new File(bg));
        BufferedImage innerImage = ImageIO.read(new File(qrFile));
        Graphics2D g2d = exImage.createGraphics();
        // 在图形和图像中实现混合和透明效果
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1));
        // 绘制
        g2d.drawImage(innerImage, 512, 930, 860, 860, null);
        g2d.dispose();
        String hotelQr = pathFolder + qrName + ".png";
        ImageIO.write(exImage, "png", new FileOutputStream(hotelQr));
        return hotelQr;
    }

    /**
     * 校验图片格式
     * @param file
     * @return
     */
    public static  boolean  checkFileLayout(MultipartFile file ) {
        String checkFilename = file.getOriginalFilename();
        String checkSuffix = FilenameUtils.getExtension(checkFilename);
        Collection collection= new ArrayList();
        collection.add("png");
        collection.add("jpeg");
        collection.add("jpg");
        return collection.contains(checkSuffix);
    }
}

 

 

 <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <hutool.version>4.5.10</hutool.version>
 </dependency>

 

package com.sf.vsolution.hb.sfce.util.verifycode;


import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
* 验证码生成工具
*/
public class VerifyCodeUtil {

/**
* 验证码类型为仅数字,0~9
*/
public static final int TYPE_NUM_ONLY = 0;
/**
* 验证码类型为仅字母,即大小写字母混合
*/
public static final int TYPE_LETTER_ONLY = 1;
/**
* 验证码类型为数字和大小写字母混合
*/
public static final int TYPE_ALL_MIXED = 2;

/**
* 验证码类型为数字和大写字母混合
*/
public static final int TYPE_NUM_UPPER = 3;

/**
* 验证码类型为数字和小写字母混合
*/
public static final int TYPE_NUM_LOWER = 4;

/**
* 验证码类型为仅大写字母
*/
public static final int TYPE_UPPER_ONLY = 5;
/**
* 验证码类型为仅小写字母
*/
public static final int TYPE_LOWER_ONLY = 6;


private VerifyCodeUtil(){}

/**
* 生成验证码
* @param request
* @param response
* @throws IOException
*/
public void getVerifyCodeImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
HttpSession session = request.getSession();
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
String verifyCode = generateTextCode(VerifyCodeUtil.TYPE_NUM_LOWER, 4, null);
response.setContentType("image/jpeg");
BufferedImage bufferedImage =generateImageCode(verifyCode, 90, 30, 3, true, Color.WHITE, Color.BLACK, null);
ImageIO.write(bufferedImage, "jpeg", response.getOutputStream());
}

/**
* 生成验证码字符串
* @param type 验证码类型,参见本类的静态属
* @param length 验证码长度,要求大于0的整数
* @param excludeString 需排除的特殊字符(无需排除则为null
* @return 验证码字符串
*/
public static String generateTextCode(int type, int length, String excludeString){
if(length <= 0){
return "";
}

StringBuffer verifyCode = new StringBuffer();
int i = 0;
Random random = new Random();
switch(type){
case TYPE_NUM_ONLY:
while(i < length){
int t = random.nextInt(10);
//排除特殊字符
if(null==excludeString || excludeString.indexOf(t+"")<0) {
verifyCode.append(t);
i++;
}
}
break;
case TYPE_LETTER_ONLY:
while(i < length){
int t = random.nextInt(123);
if((t>=97 || (t>=65&&t<=90)) && (null==excludeString||excludeString.indexOf((char)t)<0)){
verifyCode.append((char)t);
i++;
}

}
break;
case TYPE_ALL_MIXED:
while(i < length){
int t = random.nextInt(123);
if((t>=97 || (t>=65&&t<=90) || (t>=48&&t<=57)) && (null==excludeString||excludeString.indexOf((char)t)<0)){
verifyCode.append((char)t);
i++;
}
}
break;
case TYPE_NUM_UPPER:
while(i < length){
int t = random.nextInt(91);
if((t>=65 || (t>=48&&t<=57)) && (null==excludeString || excludeString.indexOf((char)t)<0)){
verifyCode.append((char)t);
i++;
}
}
break;
case TYPE_NUM_LOWER:
while(i < length){

int t = random.nextInt(123);

if((t>=97 || (t>=48&&t<=57)) && (null==excludeString || excludeString.indexOf((char)t)<0)){

verifyCode.append((char)t);

i++;

}

}

break;

case TYPE_UPPER_ONLY:
while(i < length){
int t = random.nextInt(91);
if((t >= 65) && (null==excludeString||excludeString.indexOf((char)t)<0)){
verifyCode.append((char)t);
i++;
}
}

break;
case TYPE_LOWER_ONLY:
while(i < length){
int t = random.nextInt(123);
if((t>=97) && (null==excludeString||excludeString.indexOf((char)t)<0)){
verifyCode.append((char)t);
i++;
}

}
break;
}
return verifyCode.toString();
}



/**
* 已有验证码,生成验证码图片
* @param textCode 文本验证码
* @param width 图片宽度(注意此宽度若过小,容易造成验证码文本显示不全,4个字符的文本可使用8590的宽度)
* @param height 图片高度
* @param interLine 图片中干扰线的条数
* @param randomLocation 每个字符的高低位置是否随机
* @param backColor 图片颜色,若为null则表示采用随机颜色
* @param foreColor 字体颜色,若为null则表示采用随机颜色
* @param lineColor 干扰线颜色,若为null则表示采用随机颜色
* @return 图片缓存对象
*/

public static BufferedImage generateImageCode(String textCode, int width, int height, int interLine, boolean randomLocation, Color backColor, Color foreColor, Color lineColor){
//创建内存图像
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//获取图形上下文
Graphics graphics = bufferedImage.getGraphics();
//画背景图
graphics.setColor(null==backColor ? generateRandomColor() : backColor);
graphics.fillRect(0, 0, width, height);
//画干扰线
Random random = new Random();
if(interLine > 0){
int x = 0, y = 0, x1 = width, y1 = 0;
for(int i=0; i<interLine; i++){
graphics.setColor(null==lineColor ? generateRandomColor() : lineColor);
y = random.nextInt(height);
y1 = random.nextInt(height);
graphics.drawLine(x, y, x1, y1);
}

}
//字体大小为图片高度的80%
int fsize = (int)(height * 0.8);
int fx = height - fsize;
int fy = fsize;
//设定字体
graphics.setFont(new Font("Default", Font.PLAIN, fsize));
//写验证码字符
for(int i=0; i<textCode.length(); i++){
fy = randomLocation ? (int)((Math.random()*0.3+0.6)*height) : fy;
graphics.setColor(null==foreColor ? generateRandomColor() : foreColor);
//将验证码字符显示到图象中
graphics.drawString(textCode.charAt(i)+"", fx, fy);
fx += fsize * 0.9;
}
graphics.dispose();
return bufferedImage;
}



/**
* 生成随机颜色
*/
private static Color generateRandomColor() {
Random random = new Random();
return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
}
}

posted on 2019-12-10 13:59  追风筝的人123  阅读(585)  评论(0编辑  收藏  举报

导航