参考:http://blog.csdn.net/qq_26680031/article/details/51168527

  1. package com.rd.p2p.web;
  2.  
  3. import java.awt.BasicStroke;
  4. import java.awt.Color;
  5. import java.awt.Font;
  6. import java.awt.Graphics;
  7. import java.awt.Graphics2D;
  8. import java.awt.geom.AffineTransform;
  9. import java.awt.geom.Line2D;
  10. import java.awt.image.BufferedImage;
  11. import java.io.IOException;
  12. import java.io.UnsupportedEncodingException;
  13. import java.util.ArrayList;
  14. import java.util.Arrays;
  15. import java.util.Collections;
  16. import java.util.HashMap;
  17. import java.util.List;
  18. import java.util.Map;
  19. import java.util.Random;
  20.  
  21. import javax.imageio.ImageIO;
  22. import javax.servlet.ServletOutputStream;
  23.  
  24. import org.apache.commons.lang3.StringUtils;
  25. import org.apache.poi.ss.formula.functions.T;
  26. import org.apache.struts2.convention.annotation.Action;
  27.  
  28. import com.alibaba.fastjson.JSON;
  29. import com.rd.p2p.additional.redisCaptcha.util.ResponseUtil;
  30. import com.rd.p2p.common.util.redis.RedisValidImgCodeUtils;
  31. import com.rd.p2p.core.core.Global;
  32. import com.rd.p2p.core.core.constant.Constant;
  33. import com.rd.p2p.core.core.web.BaseAction;
  34.  
  35. public class CodeAction extends BaseAction<T> {
  36.  
  37. private static final String KEY = "randomCode";
  38. //点选文字图片验证码刷新次数
  39. private static final String KEY_TOTAL = "select_random_code_total";
  40. //点选文字图片验证码验证通过次数
  41. private static final String KEY_SUCC = "select_random_code_succ";
  42. //点选文字图片验证码验证失败次数
  43. private static final String KEY_FAIL = "select_random_code_fail";
  44. //缓存时间单位秒 设置成7天
  45. private static final int CACHE_SECONDS = 604800;
  46. //定义点选文字图片验证码允许的误差值
  47. private static final int ERROR_AMOUNT = 12;// 定义允许的误差值,单位是px
  48. //生成汉字的个数
  49. private static Integer[] arr = new Integer[] {1, 2, 3, 4, 5};
  50. //汉字颜色随机范围
  51. private static Color[] colors = {Color.GRAY, Color.LIGHT_GRAY, Color.CYAN};
  52.  
  53. /**
  54. * 跳转页面
  55. * @return
  56. */
  57. @Action("/verification")
  58. public String verification() {
  59. request.setAttribute("web_url", Global.getString("web_url"));
  60. return "verification";
  61. }
  62.  
  63. /**生成验证码
  64. * @param src
  65. * @param x
  66. * @param y
  67. */
  68. @Action("/code/getVerificationCode")
  69. public void readUsingImageReaderBigcH() {
  70. ServletOutputStream outStream = null;
  71. try {
  72. // http://localhost:8080/gtop/img/149679.jpg
  73. //String url = "d:/4.png";
  74. //url = request.getSession().getServletContext().getRealPath("") + url;
  75. /* InputStream source = new FileInputStream(src);
  76. BufferedImage image = null;
  77. image = ImageIO.read(source);*/
  78.  
  79. //生成背景图片
  80. BufferedImage image = getBackGround();
  81. int hight = image.getHeight();
  82. Graphics graphics = image.getGraphics();
  83. // 设置颜色
  84. graphics.setColor(Color.red);
  85. graphics.setFont(new Font("宋体", Font.BOLD, 30));
  86.  
  87. StringBuilder sb = new StringBuilder();
  88. Random random = new Random();
  89.  
  90. //转成集合
  91. List<Integer> intList = Arrays.asList(arr);
  92. //重新随机排序
  93. Collections.shuffle(intList);
  94.  
  95. //list参数坐标参数 用于校验是否验证通过
  96. List<String> codeList = new ArrayList<String>();
  97.  
  98. int x = 0;
  99. int y = 0;
  100.  
  101. //定义随机1到arr.length某一个字不参与校验
  102. int num = random.nextInt(arr.length)+1;
  103.  
  104. for (int i = 0; i < arr.length; i++) { // 5个汉字,只点4个
  105. String ch = getRandomChineseChar();
  106.  
  107. int place = intList.get(i);
  108. if (place == 1) {
  109. x = new Random().nextInt(30) + 40; // 自己定义的位子坐标
  110. y = new Random().nextInt(30) + 40; // i=1的时候,y的值
  111. }
  112. if (place == 2) {
  113. x = new Random().nextInt(40) + 120; // 自己定义的位子坐标
  114. y = new Random().nextInt(30) + 50; // i=2的时候,y的值
  115. }
  116. if (place == 3) {
  117. x = new Random().nextInt(70) + 200; // 自己定义的位子坐标
  118. y = new Random().nextInt(50) + 100; // i=3的时候,y的值
  119. }
  120. if (place == 4) {
  121. x = new Random().nextInt(70) + 80; // i=4的时候,x的值
  122. y = new Random().nextInt(30) + 90; // 自己定义的位子坐标
  123. }
  124. if (place == 5) {
  125. x = new Random().nextInt(70) + 180; // i=4的时候,x的值
  126. y = new Random().nextInt(30) + 50; // 自己定义的位子坐标
  127. }
  128.  
  129. Constant.LOGGER.info("x:" + x + ",y:" + y + ",hight:" + hight);
  130. //字体颜色
  131. graphics.setColor(colors[random.nextInt(colors.length)]);
  132. graphics.drawString(ch, x, y);
  133. if (place != num) {
  134. sb.append(ch);
  135. codeList.add(x + "_" + y); // jsp页面坐标原点在字的中间,drawString方法坐标原点在中间
  136. }
  137. }
  138.  
  139. Constant.LOGGER.info("汉字:" + sb);
  140. //放入session
  141. //将产生的随机汉字验证码存进session中进行保存
  142. String sessionid = request.getSession().getId();
  143. RedisValidImgCodeUtils.save(sessionid + KEY, codeList);
  144. //增加验证码请求次数
  145. RedisValidImgCodeUtils.increment(KEY_TOTAL, CACHE_SECONDS);
  146.  
  147. // 可以将图片合并传入前端 也可以直接传数据汉字给前端
  148. // 创建顶部图片
  149. BufferedImage bi = new BufferedImage(image.getWidth(), 25, BufferedImage.TYPE_INT_RGB);
  150. Graphics gra = bi.getGraphics();
  151.  
  152. // 设置背景颜色
  153. gra.setColor(Color.WHITE);
  154. // 填充区域
  155. gra.fillRect(0, 0, bi.getWidth(), bi.getHeight());
  156.  
  157. // 设置边框颜色
  158. gra.setColor(Color.BLUE);
  159. // 设置边框区域
  160. gra.drawRect(1, 1, bi.getWidth() - 2, bi.getHeight() - 2);
  161.  
  162. // 设置文字背景颜色
  163. Font font = new Font("Microsoft YaHei", Font.BOLD, 16);
  164. gra.setFont(font);
  165. gra.setColor(Color.BLACK);
  166. gra.drawString("按顺序点击:" + sb.toString(), (bi.getWidth() - 10*font.getSize())/2, bi.getHeight()/2 + font.getSize()/2);//设置文字字体 与位子 居中
  167.  
  168. BufferedImage combined = new BufferedImage(image.getWidth(), image.getHeight() + bi.getHeight(), BufferedImage.TYPE_INT_RGB);
  169.  
  170. Graphics g = combined.getGraphics(); //合并
  171. g.drawImage(bi, 0, 0, null);
  172. g.drawImage(image, 0, bi.getHeight(), null);
  173. outStream= response.getOutputStream();
  174. ImageIO.write(combined, "jpg", outStream);
  175. } catch (IOException e) {
  176. e.printStackTrace();
  177. } finally {
  178. try {
  179. if (outStream != null) {
  180. outStream.close();
  181. }
  182. } catch (IOException e) {
  183. e.printStackTrace();
  184. }
  185. }
  186. }
  187.  
  188. @Action("/code/verify")
  189. public void verify() throws IOException {
  190. Map<String, Object> data = new HashMap<String, Object>();
  191. data.put("result", false);
  192. String value = request.getParameter("code");
  193. String sessionid = request.getSession().getId();
  194. if (RedisValidImgCodeUtils.get(sessionid + KEY) == null) {
  195. printWebJson(JSON.toJSONString(data));
  196. return;
  197. }
  198. List<String> sValue = (List<String>) RedisValidImgCodeUtils.get(sessionid + KEY);
  199.  
  200. //取到数据后直接清掉redis
  201. RedisValidImgCodeUtils.del(sessionid + KEY);
  202.  
  203. Constant.LOGGER.info("**前端请求数据***"+value);
  204. Constant.LOGGER.info("**后端实际数据**"+sValue.toString());
  205.  
  206. //为null 或者"" 或者 " "
  207. if (StringUtils.isBlank(value) || sValue == null || sValue.size() < 1) {
  208. printWebJson(JSON.toJSONString(data));
  209. return;
  210. }
  211.  
  212. String [] valueStr = value.split(",");
  213. if(valueStr.length != sValue.size() || valueStr.length != 4){
  214. printWebJson(JSON.toJSONString(data));
  215. return;
  216. }
  217.  
  218. /*判断坐标参数是否正确*/
  219. String str = "";
  220. for (int i = 0; i < valueStr.length; i++) {
  221. str = valueStr[i].toString();
  222. if(StringUtils.isBlank(str) || StringUtils.isBlank(sValue.get(i).toString())){
  223. printWebJson(JSON.toJSONString(data));
  224. return;
  225. }
  226. String [] vL = valueStr[i].toString().split("_");
  227. String [] svL = sValue.get(i).toString().split("_");
  228. if(vL.length != svL.length || svL.length != 2){
  229. printWebJson(JSON.toJSONString(data));
  230. return;
  231. }
  232. //x轴 y轴判断 坐标点在左上角 ,图片宽度30px 点击范围扩大12px, 范围在 x-13 < x <x+13 ;
  233. if(!(Integer.parseInt(svL[0])-ERROR_AMOUNT < Integer.parseInt(vL[0])-15 && Integer.parseInt(vL[0])-15 < Integer.parseInt(svL[0])+ERROR_AMOUNT )
  234. || !(Integer.parseInt(svL[1])-ERROR_AMOUNT < Integer.parseInt(vL[1])-15 && Integer.parseInt(vL[1])-15 < Integer.parseInt(svL[1])+ERROR_AMOUNT)){
  235. //增加验证失败次数
  236. RedisValidImgCodeUtils.increment(KEY_FAIL, CACHE_SECONDS);
  237. printWebJson(JSON.toJSONString(data));
  238. return;
  239. }
  240. }
  241. //增加验证通过次数
  242. RedisValidImgCodeUtils.increment(KEY_SUCC, CACHE_SECONDS);
  243. data.put("result", true);
  244. printWebJson(JSON.toJSONString(data));
  245. }
  246.  
  247. /**
  248. * 生成背景图片
  249. * @return
  250. */
  251. public BufferedImage getBackGround(){
  252. int width=300; //指定生成验证码的宽度
  253. int height=200; //指定生成验证码的高度
  254. BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  255. Graphics g = image.getGraphics();
  256. Graphics2D g2d = (Graphics2D)g; //创建Graphics2D对象
  257. Random random = new Random();
  258. // Font mFont = new Font("黑体", Font.BOLD, 16); //定义字体样式
  259. // g.setColor(getRandColor(200, 250)); //背景色
  260. g.fillRect(0, 0, width, height); //绘制背景
  261. // g.setFont(mFont); //设置字体
  262. g.setColor(getRandColor(180, 200)); //线条色
  263.  
  264. //绘制88根位置和颜色全部为随机产生的线条,该线条为2f
  265. for (int i = 0; i < 88; i++) {
  266. int x = random.nextInt(width-1);
  267. int y = random.nextInt(height-1);
  268. int x1 = random.nextInt(100)+1;
  269. int y1 = random.nextInt(120)+1;
  270. BasicStroke bs = new BasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);
  271. Line2D line = new Line2D.Double(x,y,x+x1,y+y1);
  272. g2d.setStroke(bs);
  273. g2d.draw(line); //绘制直线
  274. // g2d.setColor(getRandColor(random, 30, 150)); //随机每条线条的颜色
  275. }
  276.  
  277. //输出生成的验证码图片
  278. g.dispose();
  279. return image;
  280. }
  281.  
  282. private static Color getRandColor(Random random, int fc, int bc){
  283. if (fc > 255)
  284. fc = 255;
  285. if (bc > 255)
  286. bc = 255;
  287. int r = fc + random.nextInt(bc - fc);
  288. int g = fc + random.nextInt(bc - fc);
  289. int b = fc + random.nextInt(bc - fc);
  290. return new Color(r, g, b);
  291. }
  292.  
  293. private static String[] generateCheckCode() {
  294. String[] res = new String[2];
  295. Random random = new Random();
  296. int intTemp;
  297. int intFirst = random.nextInt(100);
  298. int intSec = random.nextInt(100);
  299. String checkCode = "";
  300. int result = 0;
  301. switch (random.nextInt(6)) {
  302. case 0:
  303. if (intFirst < intSec) {
  304. intTemp = intFirst;
  305. intFirst = intSec;
  306. intSec = intTemp;
  307. }
  308. checkCode = intFirst + " - " + intSec + " = ?";
  309. result = intFirst-intSec;
  310. break;
  311. case 1:
  312. if (intFirst < intSec) {
  313. intTemp = intFirst;
  314. intFirst = intSec;
  315. intSec = intTemp;
  316. }
  317. checkCode = intFirst + " - ? = "+(intFirst-intSec);
  318. result = intSec;
  319. break;
  320. case 2:
  321. if (intFirst < intSec) {
  322. intTemp = intFirst;
  323. intFirst = intSec;
  324. intSec = intTemp;
  325. }
  326. checkCode = "? - "+intSec+" = "+(intFirst-intSec);
  327. result = intFirst;
  328. break;
  329. case 3:
  330. checkCode = intFirst + " + " + intSec + " = ?";
  331. result = intFirst + intSec;
  332. break;
  333. case 4:
  334. checkCode = intFirst + " + ? ="+(intFirst+intSec);
  335. result = intSec;
  336. break;
  337. case 5:
  338. checkCode = "? + " + intSec + " ="+(intFirst+intSec);
  339. result = intFirst;
  340. break;
  341. }
  342. res[0] = checkCode;
  343. res[1] = String.valueOf(result);
  344. Constant.LOGGER.info("result=" + result);
  345. return res;
  346. }
  347.  
  348. @Action("/code/calc")
  349. public void calcCode() throws IOException{
  350. int width = 140, height = 37;
  351. try {
  352. BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  353. Graphics g = image.getGraphics();
  354. Random random = new Random();
  355. g.setColor(getRandColor(random, 200, 250));
  356. g.fillRect(0, 0, width, height);
  357.  
  358. String[] fontTypes = { "\u5b8b\u4f53", "\u65b0\u5b8b\u4f53", "\u9ed1\u4f53", "\u6977\u4f53", "\u96b6\u4e66" };
  359. int fontTypesLength = fontTypes.length;
  360.  
  361. g.setColor(getRandColor(random, 160, 200));
  362. g.setFont(new Font("Times New Roman", Font.PLAIN, 14 + random.nextInt(6)));
  363.  
  364. for (int i = 0; i < 255; i++) {
  365. int x = random.nextInt(width);
  366. int y = random.nextInt(height);
  367. int xl = random.nextInt(12);
  368. int yl = random.nextInt(12);
  369. g.drawLine(x, y, x + xl, y + yl);
  370. }
  371.  
  372. String[] result = generateCheckCode();
  373. RedisValidImgCodeUtils.save(request.getSession().getId() + "calc_code", result[1]);
  374. String [] baseChar = result[0].split(" ");
  375. for (int i = 0; i < baseChar.length; i++) {
  376. g.setColor(getRandColor(random, 30, 150));
  377. g.setFont(new Font(fontTypes[random.nextInt(fontTypesLength)], Font.BOLD, 22 + random.nextInt(6)));
  378. g.drawString(baseChar[i], 24 * i + 10, 24);
  379. }
  380. g.dispose();
  381. //发送图片
  382. ResponseUtil.sendImg(response, image, "image/jpeg", "code", "jpg");
  383. } catch (IllegalStateException e) {
  384. Constant.LOGGER.error(e.getMessage());
  385. e.printStackTrace();
  386. }
  387. }
  388.  
  389. @Action("/code/getRandomCode")
  390. public void getRandomCode() throws IOException{
  391. // TODO Auto-generated method stub
  392. //设置不缓存图片
  393. response.setHeader("Pragma", "No-cache");
  394. response.setHeader("Cache-Control", "No-cache");
  395. response.setDateHeader("Expires", 0);
  396. //指定生成的响应图片
  397. response.setContentType("image/jpeg");
  398. int width=140; //指定生成验证码的宽度
  399. int height=37; //指定生成验证码的高度
  400. BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  401. Graphics g = image.getGraphics();
  402. Graphics2D g2d = (Graphics2D)g; //创建Graphics2D对象
  403. Random random = new Random();
  404. Font mFont = new Font("黑体", Font.BOLD, 22); //定义字体样式
  405. g.setColor(getRandColor(200, 250));
  406. g.fillRect(0, 0, width, height); //绘制背景
  407. g.setFont(mFont); //设置字体
  408. g.setColor(getRandColor(180, 200));
  409.  
  410. //绘制100根位置和颜色全部为随机产生的线条,该线条为2f
  411. for (int i = 0; i < 100; i++) {
  412. int x = random.nextInt(width-1);
  413. int y = random.nextInt(height-1);
  414. int x1 = random.nextInt(6)+1;
  415. int y1 = random.nextInt(12)+1;
  416. BasicStroke bs = new BasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);
  417. Line2D line = new Line2D.Double(x,y,x+x1,y+y1);
  418. g2d.setStroke(bs);
  419. g2d.draw(line); //绘制直线
  420. }
  421.  
  422. //输出由英文,数字和中文随机组成的验证文字,具体的组合方式根据生成随机数确定
  423. String sRand = "";
  424. //输出随机的验证文字
  425. String ctmp = "";
  426. int itmp = 0;
  427. for(int i = 0;i<4;i++){
  428. switch (random.nextInt(2)) {
  429. case 0:
  430. itmp = random.nextInt(26)+65; //生成A~Z的字母
  431. ctmp = String.valueOf((char)itmp);
  432. break;
  433. default:
  434. ctmp = String.valueOf(random.nextInt(8)+2); //生成2~9的数字
  435. break;
  436. }
  437. sRand+=ctmp;
  438. Color color = new Color(20+random.nextInt(110), 20+random.nextInt(110), 20+random.nextInt(110));
  439. g.setColor(color);
  440.  
  441. //将生成的随机数进行随机缩放病旋转指定角度
  442. //将文字旋转指定角度
  443. Graphics2D g2d_word = (Graphics2D)g;
  444. AffineTransform trans = new AffineTransform();
  445. trans.rotate(random.nextInt(45)*3.14/180, 15*i+8, 7);
  446. //缩放文字
  447. /*float scaleSize = random.nextFloat()+0.8f;
  448. if(scaleSize > 1f){
  449. scaleSize = 1f;
  450. }
  451. trans.scale(scaleSize, scaleSize); */
  452. g2d_word.setTransform(trans);
  453. g.drawString(ctmp, 20*i+18, 18); //每个字的间距xy
  454. }
  455. //将生成的验证码保存道session中
  456. RedisValidImgCodeUtils.save(request.getSession().getId() + "randCheckCode", sRand);
  457.  
  458. //输出生成的验证码图片
  459. g.dispose();
  460. ImageIO.write(image, "JPEG", response.getOutputStream());
  461. }
  462.  
  463. public Color getRandColor(int s,int e){
  464. Random random = new Random();
  465. if(s>255)s = 255;
  466. if(e>255)e = 255;
  467. int r = s+random.nextInt(e-s);
  468. int g = s+random.nextInt(e-s);
  469. int b = s+random.nextInt(e-s);
  470. return new Color(r, g, b);
  471. }
  472.  
  473. public static String getRandomChineseChar() {
  474. String str = null;
  475. int hs, ls;
  476. Random random = new Random();
  477. hs = (176 + Math.abs(random.nextInt(39)));
  478. ls = (161 + Math.abs(random.nextInt(93)));
  479. byte[] b = new byte[2];
  480. b[0] = (new Integer(hs).byteValue());
  481. b[1] = (new Integer(ls).byteValue());
  482. try {
  483. str = new String(b, "GBk"); //转成中文
  484. } catch (UnsupportedEncodingException ex) {
  485. ex.printStackTrace();
  486. }
  487. return str;
  488. }
  489.  
  490. }
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. <meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
  6. <script src="${web_url}/api/themes/theme_default/media/js/jquery.js"></script>
  7. <title>验证码</title>
  8. </head>
  9. <body>
  10. <div style="text-align:center;position:relative;">
  11. <!--<h2>这是点击的验证码</h2> -->
  12. <!-- 这是点击的验证码 -->
  13. <img id="codeT3" src="${web_url}/api/code/getVerificationCode.html?flag=" +Math.random()"/>
  14. </br>
  15. <!--
  16. <input type="button" value="刷新" onclick="getCodeTree();" />
  17. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  18. <input type="button" value="校验" onclick="cheakOutTree();" />
  19. -->
  20. <select id="codeSelect" style="display: none;"></select>
  21. <img src="${web_url}/api/refresh.png" style="position:absolute;right:0;top:0; width:20px; height: 20px;" onclick="getCodeTree();" />
  22. </div>
  23.  
  24. <script type="text/javascript">
  25. //点击次数
  26. var number=0;
  27.  
  28. //获取验证码3
  29. function getCodeTree() {
  30. number = 0;
  31. $(".zhezhao").remove();
  32. document.getElementById("codeSelect").options.length = 0;
  33. $("#codeT3").attr("src","${web_url}/api/code/getVerificationCode.html?flag="+Math.random());
  34. }
  35.  
  36. $(function() {
  37. $("#codeT3").bind("click", function(ev) {
  38. var oEvent = ev || event;
  39. //var number = $("#codeSelect option").length;
  40. number++;
  41.  
  42. if (number > 4) {
  43. return;
  44. }
  45.  
  46. var x = oEvent.pageX;
  47. var y = oEvent.pageY;
  48. var img = document.getElementById('codeT3'); //获取图片的原点
  49. var nodex = getNodePosition(img)[0];//原点x 与原点y
  50. var nodey = getNodePosition(img)[1];
  51.  
  52. var xserver = parseInt(x) - parseInt(nodex);
  53. var yserver = parseInt(y) - parseInt(nodey);
  54.  
  55. $("#codeSelect").append(
  56. "<option value='"+ (parseInt(number)+1) +"'>" + xserver + "_" + yserver
  57. + "</option>");
  58. var oDiv = document.createElement('img');
  59. oDiv.style.left = (parseInt(x)-15) + 'px'; // 指定创建的DIV在文档中距离左侧的位置 图片大小30 左右移动5
  60. oDiv.style.top = (parseInt(y) -15) + 'px'; // 指定创建的DIV在文档中距离顶部的位置
  61. oDiv.style.border = '1px solid #FF0000'; // 设置边框
  62. oDiv.style.position = 'absolute'; // 为新创建的DIV指定绝对定位
  63. oDiv.style.width = '30px'; // 指定宽度
  64. oDiv.style.height = '30px'; // 指定高度
  65. //oDiv.src = 'select.png';
  66. oDiv.style.opacity = '0.5'; //透明度
  67. oDiv.className = 'zhezhao';//加class 点刷新后删除遮罩
  68. document.body.appendChild(oDiv);
  69.  
  70. //第四次点击后自动提交
  71. if (number == 4) {
  72. cheakOutTree();
  73. }
  74.  
  75. });
  76.  
  77. })
  78.  
  79. //校验验证码
  80. function cheakOutTree() {
  81. var txt = "";
  82. $("#codeSelect option").each(function (){
  83. var text = $(this).text();
  84. if(txt == ""){
  85. txt = text;
  86. }else{
  87. txt = txt + "," + text;
  88. }
  89. });
  90. $.ajax({
  91. type:"post",
  92. url:"${web_url}/api/code/verify.html",
  93. data : {"code" : txt},
  94. cache : false,
  95. success : function(data) {
  96. alert(data.result);
  97. if (!data.result) {
  98. getCodeTree();
  99. }
  100. }
  101. });
  102. }
  103.  
  104. function getNodePosition(node) {
  105. var top = left = 0;
  106. while (node) {
  107. if (node.tagName) {
  108. top = top + node.offsetTop;
  109. left = left + node.offsetLeft;
  110. node = node.offsetParent;
  111. }
  112. else {
  113. node = node.parentNode;
  114. }
  115. }
  116. return [left, top];
  117. }
  118.  
  119. </script>
  120.  
  121. </body>
  122. </html>

java实现点选汉字验证码(自己修改后的)的更多相关文章

  1. java实现点选汉字验证码(转)

    package com.rd.p2p.web; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; im ...

  2. java实现点选汉字验证码

    package com.rd.p2p.web; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; im ...

  3. 用java将excel表格中的内容修改后写入到另一个excel中

    package nn; import java.io.File; import jxl.Cell; import jxl.Sheet; import jxl.Workbook; import jxl. ...

  4. Java随机生成常用汉字验证码

    原文:http://www.open-open.com/code/view/1422514803970 import java.awt.Color; import java.awt.Font; imp ...

  5. java验证码-汉字验证码

    今天整理了一个java实现的汉字输入验证码 主要包含两个类,一个是生成验证码,一个是判断验证码输入是否正确 实现原理非常简单,将汉字和干扰线生成图片并将汉字保存到session,前台获取每次生成验证码 ...

  6. 字母数字、字母、汉字验证码 (java)

    原文:http://blog.csdn.net/qh_java/article/details/49854477 一.字母数字,字母,汉字验证码的生成代码 1.字母数字验证码: package com ...

  7. PHP算式验证码和汉字验证码的实现方法

    在PHP网站开发中,验证码可以有效地保护我们的表单不被恶意提交,但是如果不使用算式验证码或者汉字验证码,仅仅使用简单的字母或者数字验证码,这样的验证码方案真的安全吗? 大家知道简单数字或者字母验证码很 ...

  8. JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架)

    JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架) 本来想实现 QQ 登录,有域名一直没用过,还得备案,好麻烦,只能过几天再更新啦. 先把实现的发送邮箱验证码更能更新了. 老规矩,更多内容在注释 ...

  9. Eclipse Java class修改后的即时编译

    通常情况下,修改了java文件,需要重启eclipse.但是myeclipse可以不用. 其实即时编译早就有了,通过简单配置javaRebel配置,可以达到修改java文件后不重启eclipse. 注 ...

随机推荐

  1. perror表

    #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #defi ...

  2. P4160 [SCOI2009]生日快乐

    题目描述 windy的生日到了,为了庆祝生日,他的朋友们帮他买了一个边长分别为 X 和 Y 的矩形蛋糕. 现在包括windy,一共有 N 个人来分这块大蛋糕,要求每个人必须获得相同面积的蛋糕. win ...

  3. BZOJ1565 [NOI2009]植物大战僵尸 【最大权闭合子图 + tarjan缩点(或拓扑)】

    题目 输入格式 输出格式 仅包含一个整数,表示可以获得的最大能源收入.注意,你也可以选择不进行任何攻击,这样能源收入为0. 输入样例 3 2 10 0 20 0 -10 0 -5 1 0 0 100 ...

  4. C++ primer 学习笔记之容器insert

    今天在做练习9.22时,始终出现segments fault.最后才发现原来是自己对“容器insert之后迭代器会失效”的理解不够透彻. 题目如下: 假定iv是一个int的vector,下面的程序存在 ...

  5. github的使用简易教程

    一.安装git https://git-for-windows.github.io/ git  ->  git bash 二.配置参数 $ git config --global user.na ...

  6. em,rem

    em rem 相对单位:  也可用于设置padding line-height等em相对当前容器的默认字体设置比如,所有浏览器默认字体都是16px,body{ font-size:62.5%}以后即1 ...

  7. .prm详解

    一.内存分配 1.资源分布 如上图所示,单片机型号最后的数字也就代表了单片机中Flash的大小,S12G128 表示Flash有128K Byte,S12G192 表示Flash有192K Byte. ...

  8. c# tcplistener 与 client通信 服务端 今天写一下

    using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Lin ...

  9. Balanced Lineup(RMQ)

    原题传送门 就是裸RMQ啊.. 求区间最大值和区间最小值,一看就像RMQ,当然线段树貌似也可以. 至于算法嘛.自己学~(好吧,放个传送门...) 然后就是最后把maxsum-minsum就好啦233~ ...

  10. ANDROID开发笔记(二)

    动机: 开发的一个背单词的软件. 不会实现划屏的特性. 方法: 第一步尝试: 在MainActivity中, 增加以下代码后, 如果在视图的空白处点击时, 文本框中的时间就会发生改变. @Overri ...