Springboot生成随机验证码并响应

Controller层
这里一定要设置响应类型,否则不识别,
注释掉的部分是使用session存储,这里建议还是使用redis进行储存,解放服务器;如果想用session储存,需要把service部分生成图片部分拿回来,因为那里并行了一个StringBuilder收集验证码;

@Controller
@RequestMapping("/code")
public class CodeController {

    @Autowired
    private Code code;

    @RequestMapping("/img")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response, @RequestParam Integer id){
        //设置响应类型
        response.setContentType("image/jpeg");
        // 不缓存此内容
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expire", 0);
        try {
            BufferedImage imge = code.getCode(id);
           /* //这里使用Session保存验证码,建议在业务曾调用redis进行保存
            HttpSession session = request.getSession();
            session.removeAttribute("captcha");
            session.setAttribute("captcha",code.toString());
            session.setMaxInactiveInterval(-1);//设置session不会过期*/
            //必须使用write才能写出验证码
            ImageIO.write(imge,"JPEG",response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

必须使用 ImageIO.write进行写入,否则无法显示
同样的也可以用于二维码等图片的回显;首先这里的image就是图片流,response.getOutputStream获取了一个响应输出流,通过他就可以在页面上直接响应,如果是使用的本地流就会生成在本地;

Service
这里生成了随机验证码,并缓存到了redis

@Service
public class Code {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    public BufferedImage getCode(Integer id){
        String redisKey = id+"USERCODE";
        int width = 250;
        int height= 60;

        //生成对应宽高的初始图片
        BufferedImage verifyImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
        //调用方法把画板给他,生成验证码字符串,加上随机线和噪点,返回值为验证码字符串
        String ranCode = new Code().drawRandomText(width,height,verifyImg);
        System.out.println("验证码为:"+ranCode);
        //将验证码缓存到redis
        redisTemplate.opsForValue().set(redisKey,ranCode, Duration.ofMinutes(5));

        return verifyImg;
    }

    //图片处理
    public String drawRandomText(int width,int height,BufferedImage verifyImg){
        //在传过来的画板上开一个2d画笔
        Graphics2D graphics =(Graphics2D)verifyImg.getGraphics();
        //设置画笔颜色
        graphics.setColor(Color.white);//这个给验证码背景好了
        //用笔填充背景操作指定范围
        graphics.fillRect(0,0,width,height);
        //设置字体
        graphics.setFont(new Font("黑体",Font.BOLD,40));
        //设置一个字符池
        String baseNumLetter="1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";

        StringBuffer stringBuffer = new StringBuffer();
        int x= 10;//原点的坐标
        //预设一个空字符
        String ch = "";
        //来一个循环一次循环生成一个随机code字符
        Random ran=new Random();
        for (int i = 0; i < 5; i++) {
            //先获取一个随机颜色,设置在画笔对象上
            graphics.setColor(getRandomColor());
            int degree = ran.nextInt()%30;//角度小于30度,生成随机+-30范围百,这里用来表示角度
            //基于字符池长度生成随机索引,一会取字符用
            int dot = ran.nextInt(baseNumLetter.length());
            //根据随机取出的下标索引随机区一个字符
            ch =baseNumLetter.charAt(dot)+"";
            //将取出的字符追加上去。这里只是收集验证码最终结果而已,方便一会返回,下面写入的时候是按照临时的ch写入
            stringBuffer.append(ch);
            //操纵画笔正向旋转degree度。上面定义好的一个数字X为X轴坐标
            graphics.rotate(degree*Math.PI/180,x,45);
            //操纵画笔写下字符(内容,X轴,Y轴)
            graphics.drawString(ch,x,45);
            //将画笔旋转回来
            graphics.rotate(-degree*Math.PI/180,x,45);
            //推进画笔的x轴值。
            x+=48;
        }
        //循环结束5个字符写上去了
        //画干扰线画几条随便
        for (int i = 0; i < 8; i++) {
            //给画笔涂上随机颜色
            graphics.setColor(getRandomColor());
            //操纵画笔随机画线,传参设置线条的长度宽度距离边缘的长度宽度
            graphics.drawLine(ran.nextInt(width),ran.nextInt(height),ran.nextInt(width),ran.nextInt(height));
        }
        //添加噪点,这个多整点
        for (int i = 0; i < 40; i++) {
            int xx = ran.nextInt(width);
            int yy = ran.nextInt(height);
            //给画笔涂上随机颜色
            graphics.setColor(getRandomColor());
            //下手画点,给出上面定义好的位置坐标,以及像素宽度长度
            graphics.fillRect(xx,yy,2,2);
        }
        //画板已经画完了,顺便将收集好的验证码return出去;
        return stringBuffer.toString();
    }



    //获取随机颜色的方法
    private Color getRandomColor() {
        Random ran=new Random();
        Color color=new Color(ran.nextInt(256),ran.nextInt(256),ran.nextInt(256));
        return color;
    }
}

效果:
在这里插入图片描述
在这里插入图片描述

调用方法生成验证码并缓存结束后返回。。。复制即可用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值