https://vimsky.com/zh-tw/examples/detail/java-class-javax.servlet.ServletOutputStream.html

开发过程中,需要服务端返回验证码图片给前台,想想该如何实现呢?

1、字节流的输入输出
2、生成一个验证码,自定义字母数字混合实现
3、生成一个图片,可以自定义颜色设置

上代码,看结果。

/*** 生成验证码图片** @return*/public Map<String, Object> generateIdentifyCode(HttpServletRequest request, int width, int height) {Map<String, Object> map = new HashMap<>(2);String uniqueId = this.getUniqueIdFromCookie(request);if (StringUtils.isBlank(uniqueId)) {uniqueId =System.nanoTime() + RandomStringUtils.randomAlphanumeric(10);}int num = Integer.valueOf(codeLength);//生成随机码String capText = this.getIdentifyingCode(num);//redis 缓存存储,用于校验// redisClient.setex(getIdentifyingCodePreKey(uniqueId), 180, capText);map.put("image", this.img(width, height, num, capText));map.put("uniqueId", uniqueId);return map;}
/*** 获取cookie中的uniqueId** @param request* @return*/private String getUniqueIdFromCookie(HttpServletRequest request) {String uniqueId = "";Cookie[] cookies = request.getCookies();if (cookies != null) {for (Cookie cookie : cookies) {if (cookie.getName().endsWith("_UNIQUE_ID")) {uniqueId = cookie.getValue();break;}}}return uniqueId;}
/*** 生成图片** @param width* @param height* @param num* @param capText* @return*/public BufferedImage img(int width, int height, int num, String capText) {int x = width / (num + 1);int fontHeight = height - 2;int codeY = height - 4;// 定义图像bufferBufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics2D g = buffImg.createGraphics();// 创建一个随机数生成器类Random random = new Random();// 将图像填充为白色g.setColor(Color.WHITE);g.fillRect(0, 0, width, height);// 创建字体,字体的大小应该根据图片的高度来定Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);// 设置字体g.setFont(font);// 画边框g.setColor(Color.WHITE);g.drawRect(0, 0, width - 1, height - 1);// 随机产生160条干扰线,使图像中的认证码不易被其他程序探测到g.setColor(Color.BLACK);for (int i = 0; i < 10; i++) {int xx = random.nextInt(width);int yy = random.nextInt(height);int x1 = random.nextInt(10);int y1 = random.nextInt(12);g.drawLine(xx, yy, xx + x1, yy + y1);}// randomCode用于保存随机产生的验证码,以便用户登录后进行验证String randomCode = capText;int red = 0, green = 0, blue = 0;// 随机产生codeCount数字的验证码for (int i = 0; i < randomCode.length(); i++) {// 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同red = random.nextInt(255);green = random.nextInt(255);blue = random.nextInt(255);// 用随机产生的颜色将验证码绘制到图像中g.setColor(new Color(red, green, blue));g.drawString(String.valueOf(randomCode.charAt(i)), (i + 1) * x, codeY);}return buffImg;}
/*** 生成随机码** @param num* @return*/private String getIdentifyingCode(int num) {Random random = new Random();String codeStr = "";// 生成验证码for (int i = 0; i < num; i++) {codeStr += String.valueOf(CODE_SEQUENCE[random.nextInt(36)]);}return codeStr;}
/*** 验证码长度*/@Value("5")private String codeLength;/*** 验证码字符*/private static final char[] CODE_SEQUENCE = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J','K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W','X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

controller代码:

@RequestMapping(value = "generate", method = RequestMethod.GET)public String generateIdentifyCode(HttpServletRequest request, HttpServletResponse response,@RequestParam(value = "width", required = false, defaultValue = "100") int width,@RequestParam(value = "height", required = false, defaultValue = "30") int height) {response.setDateHeader("Expires", 0);response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");response.addHeader("Cache-Control", "post-check=0, pre-check=0");response.setHeader("Pragma", "no-cache");//生成图片上的文字Map<String, Object> map = identifyingCodeService.generateIdentifyCode(request, width, height);String uniqueId = (String) map.get("uniqueId");Cookie cookie = new Cookie("_UNIQUE_ID", uniqueId);//60s过期cookie.setMaxAge(120);cookie.setPath("/");response.addCookie(cookie);ServletOutputStream out = null;try {out = response.getOutputStream();ImageIO.write((BufferedImage) map.get("image"), "jpg", out);// 强制将缓冲区所有的数据输出!out.flush();} catch (IOException e) {// ApiLogger.error("generate identify code is error, e " + e);} finally {try {if (null != out) {out.close();}} catch (IOException e) {// ApiLogger.error("generate identify code, close out is error, e " + e);}}return null;}

返回结果:

验证起来也方便,因为在创建验证码的时候已经在redis存储了value,直接请求对比验证即可。
需注意:图片生成大小调整还是得根据想要的验证码位数来调试长宽高

java 生成图片验证码相关推荐

  1. 用java如何做图片验证码,运用java生成图片验证码

    使用java生成图片验证码 本程序来源以下网址:http://www.linux521.com/2009/java/200909/8475.html 仅供学习和参考 import java.awt.B ...

  2. 后端生成图片验证码,Kotlin生成图片验证码,Java生成图片验证码,图片验证码的生成和校验

    后端生成图片验证码 注:以下代码主要使用kotlin进行编写,kotlin可兼容java,可以直接使用.IDEA也支持将java与kotlin代码进行互相转换. 1.引入依赖: Gradle(若你使用 ...

  3. Java生成图片验证码(有点仿QQ验证码的意思)

    看了挺多图片验证码的代码,感觉没什么长的好看点的,就自己动手写了个,写完发现跟QQ的有几分相似,比较满意. 功能包括:自定义图片尺寸和字符长度,随机背景颜色和字符颜色,随机字符偏移角度,字符平滑边缘, ...

  4. java 生成图片验证码结合struts2使用

    验证码生成器类 package com.itest.util; import java.awt.Color; import java.awt.Font; import java.awt.Graphic ...

  5. Java 生成图片验证码(包含全是字母、加减乘除、中文)3种方法

    如果你有幸看到这个篇文章  看了之后对你有帮助 请点赞 关注 评论 谢谢 第一种方法 全是字母和数字组成 package com.myFirstSpring.util;import java.awt. ...

  6. java生成图片验证码

    2019年8月29日17:52:34 public class CodeUtil {private static int width = 90;// 定义图片的widthprivate static ...

  7. Java代码生成图片验证码

    Java生成图片验证码 1.编写代码 copy 下面的代码 并运行main函数 import javax.imageio.ImageIO; import java.awt.*; import java ...

  8. java 3d验证码_Java实现验证码具体代码(图片、汉字)

    本文为大家分享两个实例,相信大家一定会喜欢. 实例1:随机生成验证码图片并将之输出为一个png文件 效果图: import java.awt.Color; import java.awt.Font; ...

  9. java生成验证码图片中仅有线条_Java实现验证码具体代码(图片、汉字)

    本文为大家分享两个实例,相信大家一定会喜欢. 实例1:随机生成验证码图片并将之输出为一个png文件 效果图: import java.awt.Color; import java.awt.Font; ...

最新文章

  1. Glide的缓存机制
  2. 第十三届光华工程科技奖名单揭晓!这40位专家和1个团体获奖
  3. MySQL基础篇:数据操作语言DML
  4. 本地windows上传大文件到Linux服务器工具的选择以及使用方法
  5. python基础学习笔记2
  6. 和煤一样的黑色矿石_煤精?黑琥珀?煤球一样的东西这么值钱!
  7. javax.mail.AuthenticationFailedException: 535 authentication failed的问题
  8. java实现记事本查找_Java实现记事本
  9. 用友政务知识管理平台_云创数字政务大数据平台,助力政务工作高效管理
  10. 关于delete字符串 需不需要加 [ ]
  11. Flutter实战一Flutter聊天应用(汇总)
  12. android 多个模块,Android Studio:多个模块的多个APK
  13. hg更新下载指定版本
  14. html 做报表,创建 HTML 报表
  15. Python基础知识从hello world 开始(第三天)
  16. html复选框,不打勾默认值是0,打钩默认值是1,方框打钩符号复制(一招教你方框里打勾的符号)...
  17. 网络安全之黑客入侵的步骤
  18. Unity粒子系统——简易特效制作(三)
  19. 家用数码相机选购及使用指南
  20. Codeforces Round #835 (Div. 4) - D. Challenging Valleys

热门文章

  1. 【Android】项目中音频文件的存储位置
  2. 【笔记】95%置信区间:一般我们用中括号[a,b]表示样本估计总体平均值误差范围的区间,a、b的具体数值取决于你对于“该区间包含总体均值“这一结果的可信程度,因此[a,b]被称为置信区间
  3. 2021-05-29Leetcode560.和为k的子数组
  4. 工业以太网交换机MODBUS协议总线光纤转换器工厂控制系统
  5. 浅谈幼儿园计算机论文,浅谈幼儿园班级管理论文
  6. raid5坏了一块盘怎么办_电磁炉维修|电磁炉e6怎么办
  7. 让科汛CMS在会员投稿成功后进入查看文章页面
  8. Hdu1914稳定婚姻匹配
  9. [jvm][面试]JVM 调优总结
  10. 基于javaWeb的固定资产管理系统