Java Seckill Module:Digital formula verification code

mac2024-10-12  50

上期回顾:Java Seckill Module:Seckill interface address hiding

思路:点击秒杀之前,先输入验证码,分散用户请求。

步骤:

1.添加生成验证码的接口 2.在获取秒杀路径的时候,验证验证码 3.ScriptEngine使用


进入商品详情页,首先去服务端拉取商品详情信息,拉取之后做一个渲染页面,渲染后再做一个倒计时,如果秒杀还没开始则生成倒计时信息,如果秒杀进行中,则分开按钮,秒杀结束,按钮给disabled掉。

只需要在秒杀进行中添加验证码:

<img id="verifyCodeImg" width="80" height="32" style="display:none" οnclick="refreshVerifyCode()"/> <input id="verifyCode" class="form-control" style="display:none"/> function countDown(){ var remainSeconds = $("#remainSeconds").val(); var timeout; if(remainSeconds > 0){ $("#buyButton").attr("disabled", true); $("#miaoshaTip").html("秒杀倒计时:"+remainSeconds+"秒"); timeout = setTimeout(function(){ $("#countDown").text(remainSeconds - 1); $("#remainSeconds").val(remainSeconds - 1); countDown(); },1000); }else if(remainSeconds == 0){ $("#buyButton").attr("disabled", false); if(timeout){ clearTimeout(timeout); } $("#miaoshaTip").html("秒杀进行中"); $("#verifyCodeImg").attr("src", "/miaosha/verifyCode?goodsId="+$("#goodsId").val()); $("#verifyCodeImg").show(); $("#verifyCode").show(); }else{ $("#buyButton").attr("disabled", true); $("#miaoshaTip").html("秒杀已经结束"); $("#verifyCodeImg").hide(); $("#verifyCode").hide(); } } 解读:秒杀进行中生成验证码,结束则取消验证码显示。 function refreshVerifyCode(){ $("#verifyCodeImg").attr("src", "/miaosha/verifyCode?goodsId="+$("#goodsId").val()+"&timestamp="+new Date().getTime()); } 解读:刷新验证码,浏览器对图片有缓存,所以需要new Date().getTime()。

服务端生成验证码的接口:

//映射请求,指定控制器可以处理哪些URL请求,相当于Servlet中在web.xml中配置 @RequestMapping(value="/verifyCode", method=RequestMethod.GET) @ResponseBody public Result<String> getMiaoshaVerifyCod(HttpServletResponse response, MiaoshaUser user, @RequestParam("goodsId")long goodsId) { if(user == null) { return Result.error(CodeMsg.SESSION_ERROR); } try { BufferedImage image = miaoshaService.createVerifyCode(user, goodsId); OutputStream out = response.getOutputStream(); ImageIO.write(image, "JPEG", out); out.flush(); out.close(); return null; }catch(Exception e) { e.printStackTrace(); return Result.error(CodeMsg.MIAOSHA_FAIL); } } ***** 生成验证码: public BufferedImage createVerifyCode(MiaoshaUser user, long goodsId) { if(user == null || goodsId <=0) { return null; } int width = 80; int height = 32; BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = image.getGraphics(); g.setColor(new Color(0xDCDCDC)); g.fillRect(0, 0, width, height); g.setColor(Color.black); g.drawRect(0, 0, width - 1, height - 1); Random rdm = new Random(); for (int i = 0; i < 50; i++) { int x = rdm.nextInt(width); int y = rdm.nextInt(height); g.drawOval(x, y, 0, 0); } String verifyCode = generateVerifyCode(rdm); g.setColor(new Color(0, 100, 0)); g.setFont(new Font("Candara", Font.BOLD, 24)); g.drawString(verifyCode, 8, 24); g.dispose(); int rnd = calc(verifyCode); redisService.set(MiaoshaKey.getMiaoshaVerifyCode, user.getId()+","+goodsId, rnd); return image; } 解读:我们会把验证码加载到redis中去。 private static int calc(String exp) { try { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); return (Integer)engine.eval(exp); }catch(Exception e) { e.printStackTrace(); return 0; } } private static char[] ops = new char[] {'+', '-', '*'}; 生成验证码 private String generateVerifyCode(Random rdm) { int num1 = rdm.nextInt(10); int num2 = rdm.nextInt(10); int num3 = rdm.nextInt(10); char op1 = ops[rdm.nextInt(3)]; char op2 = ops[rdm.nextInt(3)]; String exp = ""+ num1 + op1 + num2 + op2 + num3; return exp; } 验证码有效期: public static MiaoshaKey getMiaoshaVerifyCode = new MiaoshaKey(300, "vc");

生成验证码过程:首先画一张图片,把验证码生成出来给画到图片上,然后保存到redis中后,在我们从服务端获取秒杀地址的时候,需要进行下验证码的验证:

@ResponseBody public Result<String> getMiaoshaPath(HttpServletRequest request, MiaoshaUser user, @RequestParam("goodsId")long goodsId, @RequestParam(value="verifyCode", defaultValue="0")int verifyCode ) { if(user == null) { return Result.error(CodeMsg.SESSION_ERROR); } boolean check = miaoshaService.checkVerifyCode(user, goodsId, verifyCode); if(!check) { return Result.error(CodeMsg.REQUEST_ILLEGAL); } String path = miaoshaService.createMiaoshaPath(user, goodsId); return Result.success(path); } ***** public boolean checkVerifyCode(MiaoshaUser user, long goodsId, int verifyCode) { if(user == null || goodsId <=0) { return false; } Integer codeOld = redisService.get(MiaoshaKey.getMiaoshaVerifyCode, user.getId()+","+goodsId, Integer.class); if(codeOld == null || codeOld - verifyCode != 0 ) { return false; } redisService.delete(MiaoshaKey.getMiaoshaVerifyCode, user.getId()+","+goodsId); return true; }

解读:获取已经存在redis中的验证码,如果不是空的,则将redis中的验证码值与我们传进来的验证码进行比较,如果相等,则表示验证成功,接着删除掉redis中存放的验证码。

在getMiaoshaPath中收到请求之后,做一个验证码的验证,通过的话就继续执行。

function getMiaoshaPath(){ var goodsId = $("#goodsId").val(); g_showLoading(); $.ajax({ url:"/miaosha/path", type:"GET", data:{ goodsId:goodsId, verifyCode:$("#verifyCode").val() }, success:function(data){ if(data.code == 0){ var path = data.data; doMiaosha(path); }else{ layer.msg(data.msg); } }, error:function(){ layer.msg("客户端请求有误"); } }); }

 

 

 

 

最新回复(0)