WEB-APP では、ログイン、登録、特定のチケットの購入、フラッシュ セールなどのシナリオで一般的に使用されます。今日は、編集者がこの検証の実装方法を説明します。言うまでもなく、ログイン、登録、特定のチケットの購入、フラッシュセールなどで使用される
認証コードをダウンロードしてください。シナリオ。誰もがそれらに触れたことがあるでしょう。それらはあらゆる種類の奇妙で多様なものであると言えます。
デモ対象関数
確認コードページを入力してください。
ページ置換検証コード(非同期実装)。
バックエンドを検証し、検証結果を返します。
工事開始
ページ:demo1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <title>验证示例</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <style type="text/css"> img { width: 87px; height: 33px; border: 1px solid gray; } #msg {color: red;} /* 后台返回的验证信息显示为红色 */ </style> </head> <body> <form action="${pageContext.request.contextPath}/check" method="post" enctype="application/x-www-form-urlencoded"> 验证码:<input type="text" name="code" size="4" maxlength="4" id="code" /> <img id="code-img" src="" alt="验证码" style="display: none;"/> <a href="javascript:void(0)" rel="external nofollow" id="changeCode">看不清?换一张</a> <br/><br/> <input type="submit" value="验证"/> <span id="msg">${msg}</span> </form> </body> </html>
説明:
「はっきり見えない?変更してください」のhref属性はjavascript:voidと記述されています(0)
ページの更新を防ぐため、ここでの置換関数は AJAX によって非同期で完了します。 RJavaScript ツール: Util.js javascript:void(0)
是为了防止页面刷新,这里的更换功能交给 AJAX 异步完成。
JavaScript 工具:util.js(为啥用原生 JS?任性呗~哈)
/** * 获取 XMLHttpRequest Object * @returns XMLHttpRequest Object */ function getXHR() { var xmlHttp; try { // Firefox, Opera 8.0+, Safari xmlHttp = new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("Sorry, 您的浏览器不支持 AJAX!"); return false; } } } return xmlHttp; }
页面中的 JavaScript 代码
<script type="text/javascript" src="${pageContext.request.contextPath}/js/util.js"></script> <script type="text/javascript"> var xhr = getXHR(); // 获得 XMLHttpRequest 对象 // 页面加载时加载验证码,但验证码初始为隐藏状态 window.onload=function() { // 为 onreadystatechange 事件注册回调函数。由于 xhr 为全局变量,所以注册后就不用管啦 xhr.onreadystatechange=function() { if(xhr.readyState==4 && xhr.status==200) { document.getElementById('code-img').src="data:image/png;base64,"+xhr.responseText; } } xhr.open("GET","${pageContext.request.contextPath}/captcha/code",true); xhr.send(null); } // 验证码输入框获得焦点时,验证码状态更改为显示 document.getElementById('code').onfocus=function() { document.getElementById('code-img').style.display="inline"; } // 异步请求,更换验证码 document.getElementById('changeCode').onclick=function() { xhr.open("GET","${pageContext.request.contextPath}/captcha/code",true); xhr.send(null); } </script>
生成验证码的 CaptchaCodeServlet.java
package com.leo.web.captcha; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.leo.util.ImageUtil; import cn.dsna.util.images.ValidateCode; @WebServlet("/captcha/code") public class CaptchaCodeServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 生成验证码(构造参数分别代表:宽度,高度,字符数,干扰线条数) ValidateCode code = new ValidateCode(87, 33, 4, 23); // 将验证码保存到 session 中,用于验证 request.getSession().setAttribute("code", code.getCode()); // 响应返回验证码图片 base64 编码后的数据给浏览器 response.getWriter().write(ImageUtil.encodeImg2Base64(code.getBuffImg(), "png")); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
说明:
这里使用了 Servlet3.0
的新特性-用注解配置 url-pattern
(用起来挺爽的),也就是说简单的项目不再需要 web.xml
了,但是 Tomcat
需要 7.0+。
其次生成验证码我用了一个小工具:ValidateCode.jar。工具十分简单,不合心意完全可以自己写。但也就是因为功能太少,所以我又写了一个 ImageUtil
。我也有打算自己开源一个验证码工具出来。
ImageUtil.java
package com.leo.util; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import sun.misc.BASE64Encoder; public class ImageUtil { /** * 将图片二进制数据进行 base64 编码 * @param bufImg * @return base64 编码后的字符串 */ public static String encodeImg2Base64(BufferedImage bufImg, String formatName) { ByteArrayOutputStream outputStream = null; try { outputStream = new ByteArrayOutputStream(); ImageIO.write(bufImg, formatName, outputStream); } catch (IOException e) { throw new RuntimeException("Base64 编码失败!"+e.getMessage()); } BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(outputStream.toByteArray()); } private ImageUtil() {} // 工具类私有化构造方法是常见的做法 }
说明:
为什么要把图片二进制数据进行 Base64编码 呢?因为79d7c95122630a3791db16c5259dc98d
标签虽然可以直接设置 src
属性值为${pageContext.request.contextPath}/captcha/code
请求相应的 Servlet 来得到二进制数据直接显示,但在 AJAX 异步请求中响应返回的是 xhr.responseText
。当把数据直接给 img
标签的 src
属性时,用 Chrome-tool
查看只会是一堆二进制当作文本解析的乱码字符,所以才要多这一步。
或许我作为萌新不知道一些其它的方便技巧。但若不想使用异步,那直接 img src
设置为请求地址将是最简单的选择,更换验证码无非是监听事件 img src
説明:
Servlet3.0
の新機能がここで使用されています - アノテーションを使用して url-pattern
を構成します (これを使用すると非常に楽しいです) )、これは単純であることを意味します。プロジェクトには web.xml
は必要なくなりましたが、Tomcat
には 7.0 以降が必要です。
ImageUtil
を作成しました。私自身も検証コードツールをオープンソース化する予定です。 ImageUtil.java
package com.leo.web.controller; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/check") public class CheckServlet extends HttpServlet { private static final long serialVersionUID = -6588625852621588221L; @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String encoding = "UTF-8"; request.setCharacterEncoding(encoding); response.setContentType("text/html;charset="+encoding); /* 验证码验证 */ String inputCode = request.getParameter("code"); // 获得 session 中的正确验证码 String realCode = (String) request.getSession().getAttribute("code"); System.out.println("input: "+inputCode+"\nreal: "+realCode); // 用于 Debug if(!(inputCode!=null && realCode!=null && inputCode.equalsIgnoreCase(realCode))) { // 若验证码不正确:回到页面并提示错误 request.setAttribute("msg", "验证码错误!请重新输入"); request.getRequestDispatcher("/demo1.jsp").forward(request, response); return; } // 验证码正确,响应一句话表示 OK response.getWriter().write("验证成功!"); } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
説明:
画像バイナリデータを Base64 エンコードする必要があるのはなぜですか? 79d7c95122630a3791db16c5259dc98d
タグは src
属性値を ${pageContext.request.contextPath}/captcha/code
に直接設定できるためです。 > request 対応するサーブレットはバイナリ データを取得して直接表示するために使用されますが、AJAX 非同期リクエストで返される応答は xhr.responseText
です。データが img
タグの src
属性に直接与えられている場合、 Chrome-tool
を使用してデータを表示すると、大量のデータが表示されるだけです。文字化けしたバイナリ コードが文字として解析されるため、この追加の手順が必要です。
img src
をリクエスト アドレスとして直接設定するのが最も簡単な選択です。これは、イベント img src をリッスンするだけです。
を実行し、このアドレスにリセットします (もう 1 つのリクエスト)。 詳細情報: JSがブラウザでBase64エンコードされた画像を解析します
Base64画像エンコード解析とブラウザ互換処理バックエンド検証検証コード: CheckServlet.jave
rrreee
説明:
以上が検証コード機能を実装するための JavaWeb コードの詳細 (デモ)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。