captcha库_将CAPTCHA添加到您的GWT应用程序

captcha库

什么是验证码?
在一个充满恶意机器人的世界中,您应该怎么做才能保护您宝贵的Web应用程序? 您真正应该做的基本事情之一就是向其中添加CAPTCHA功能。 如果您不熟悉(听起来有些奇怪),则CAPTCHA是确保用户实际上是真实人物而不是计算机的简单方法。 这可以通过挑战用户并要求他提供对“问题”的响应来完成。 由于计算机无法解决验证码问题,因此假定输入正确解决方案的任何用户都是人。 最常见的方法是要求用户从出现在屏幕上的变形图像中键入字母或数字。

注册网站时,您很可能已经看到了一个验证码文件。 以下是来自维基百科的CAPTCHA示例。


将SimpleCaptcha添加到您的应用程序
在本教程中,我将CAPTCHA功能集成到Web应用程序中。 我将使用SimpeCaptcha框架 ,该框架用于为Java生成CAPTCHA图像/答案对。 该站点提供了一个安装指南 ,但是该指南指的是普通的基于JSP的旧应用程序。 我将向您展示如何将该框架与您喜欢的GWT项目集成。

(我将假定您已经在系统上启动并运行了GWT ,以及用于Eclipse的Google插件 )

首先,让我们创建我们的Eclipse项目。 选择文件 ? Web应用程序项目”,并提供必要的信息,如下图所示。 该项目的名称将为“ CaptchaGwtProject”。 确保包括对GWT的支持,但不包括Google App Engine。

在继续之前,请注意此处。 SimpleCaptcha大量使用AWT类来执行图像渲染。 但是,您可能知道,App Engine不支持所有JRE类,最具体地说,其中仅包含AWT包中的几个。 您可以查看AppEngine JRE类白名单以了解更多详细信息。 因此,不可能将框架合并到将在App Engine上部署的应用程序中,并且仅应将其与在标准JRE上运行的平台一起使用。

下一步是从SourceForge下载该库(我使用1.1.1版本 )。 将下载的JAR文件添加到项目的类路径中。 另外,不要忘记将JAR文件复制到“ CaptchaGwtProject \ war \ WEB-INF \ lib”文件夹,因为嵌入式容器的(Jetty)运行时将需要该文件。 您可以在此处找到该项目的JavaDoc页面。

设置客户端
Eclipse将自动创建应用程序的框架,并创建一些示例文件。 找到CaptchaGwtProject类,它是应用程序的入口点。 删除现有内容,并将其替换为以下内容:

package com.javacodegeeks.captcha.client;import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;public class CaptchaGwtProject implements EntryPoint {private final SignupServiceAsync signupService = GWT.create(SignupService.class);private final Button sendButton = new Button("Sign Up");public void onModuleLoad() {final TextBox usernameField = new TextBox();usernameField.setText("Username here");final TextBox passwordField = new TextBox();passwordField.setText("Password here");final TextBox captchaField = new TextBox();captchaField.setText("CAPTCHA Word here");final Label responseLabel = new Label();        final Image captchaImage = new Image("/SimpleCaptcha.jpg");usernameField.setFocus(true);sendButton.addStyleName("sendButton");RootPanel.get("usernameFieldContainer").add(usernameField);RootPanel.get("passwordFieldContainer").add(passwordField);RootPanel.get("captchaFieldContainer").add(captchaField);RootPanel.get("sendButtonContainer").add(sendButton);RootPanel.get("captchaImageContainer").add(captchaImage);RootPanel.get("responseLabelContainer").add(responseLabel);class MyHandler implements ClickHandler, KeyUpHandler {public void onClick(ClickEvent event) {sendDataToServer();}public void onKeyUp(KeyUpEvent event) {if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {sendDataToServer();}}private void sendDataToServer() {                String username = usernameField.getText();String password = passwordField.getText();String captcha = captchaField.getText();sendButton.setEnabled(false);    signupService.performSignup(username, password, captcha, signupCallback);                }}MyHandler handler = new MyHandler();sendButton.addClickHandler(handler);usernameField.addKeyUpHandler(handler);}private AsyncCallback signupCallback = new AsyncCallback() {        @Overridepublic void onSuccess(Boolean result) {if (result) {Window.alert("CAPTCHA was valid");}else {Window.alert("CAPTCHA was invalid");}            sendButton.setEnabled(true);}        @Overridepublic void onFailure(Throwable caught) {Window.alert("Error occurred while communicating with server");sendButton.setEnabled(true);}        };}

该代码简单明了,并且基于自动创建的示例类。 我们为用户输入添加了两个TextBox ,为服务器响应添加了Label 。 我们还添加了一个Image实例,它将作为我们的验证码的占位符。 我们将其URL设置为“ /SimpleCaptcha.jpg”,该URL将由框架处理。 最后,使用一个Button来调用对服务器的调用。 AsyncCallback使用布尔值来表示服务器上验证码验证失败的成功。 请注意,故意遗漏了Web应用程序的某些基本部分(例如用户输入验证),因此我们可以专注于CAPTCHA部分。

接下来,在项目的“ war”文件中找到名为“ CaptchaGwtProject.html”HTML文件。 编辑文件并为我们的GWT对象添加一些容器。 代码如下:

<!doctype html>
<!-- The DOCTYPE declaration above will set the    -->
<!-- browser's rendering engine into               -->
<!-- "Standards Mode". Replacing this declaration  -->
<!-- with a "Quirks Mode" doctype may lead to some -->
<!-- differences in layout.                        --><html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><!--                                                               --><!-- Consider inlining CSS to reduce the number of requested files --><!--                                                               --><link type="text/css" rel="stylesheet" href="CaptchaGwtProject.css"><!--                                           --><!-- Any title is fine                         --><!--                                           --><title>Web Application Starter Project</title><!--                                           --><!-- This script loads your compiled module.   --><!-- If you add any GWT meta tags, they must   --><!-- be added before this line.                --><!--                                           --><script type="text/javascript" language="javascript" src="captchagwtproject/captchagwtproject.nocache.js"></script></head><!--                                           --><!-- The body can have arbitrary html, or      --><!-- you can leave the body empty if you want  --><!-- to create a completely dynamic UI.        --><!--                                           --><body><!-- OPTIONAL: include this if you want history support --><iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe><!-- RECOMMENDED if your web app will not function without JavaScript enabled --><noscript><div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">Your web browser must have JavaScript enabledin order for this application to display correctly.</div></noscript><h1>CAPTCHA Secured Web Application</h1><table align="center"><tr><td colspan="2" style="font-weight:bold;">Please enter your username:</td><td id="usernameFieldContainer"></td></tr><tr><td colspan="2" style="font-weight:bold;">Please enter your password:</td><td id="passwordFieldContainer"></td></tr><tr><td colspan="2" style="font-weight:bold;">Please enter the word:</td><td id="captchaFieldContainer"></td></tr><tr><td id="sendButtonContainer"></td> </tr><tr><td id="captchaImageContainer"></td> </tr><tr><td colspan="2" style="color:red;" id="responseLabelContainer"></td></tr></table></body>
</html>

请注意,对自动生成的文件的唯一更改是在<h1>标记之后。

我们的异步GWT服务将非常简单,仅执行一项功能。 相应的两个接口如下所示:

package com.javacodegeeks.captcha.client;import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;@RemoteServiceRelativePath("signup")
public interface SignupService extends RemoteService {boolean performSignup(String username, String password, String userCaptcha);}
package com.javacodegeeks.captcha.client;import com.google.gwt.user.client.rpc.AsyncCallback;public interface SignupServiceAsync {void performSignup(String username, String password, String userCaptcha,AsyncCallback callback);}

(请注意,自动生成的“ greetingService”类已被删除)

准备服务器端
在服务器端,我们从库中使用的主要对象是Captcha 。 要检索验证码的值(并将其与用户输入进行比较),我们必须获取对与特定会话关联的HttpSession对象的引用。 可以通过相应的HttpServletRequest对象检索HttpSession。 这是标准的Java EE内容。 不要忘记服务器端GWT服务继承自RemoteServiceServlet ,而RemoteServiceServlet继承自HttpServletRequest。 可以通过调用getThreadLocalRequest方法获得基础请求。 请注意,正如API所提到的,这是本地存储在线程中的,因此同时调用可以具有不同的请求对象。

服务器端的具体实现如下:

package com.javacodegeeks.captcha.server;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;import nl.captcha.Captcha;import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.javacodegeeks.captcha.client.SignupService;@SuppressWarnings("serial")
public class SignupServiceImpl extends RemoteServiceServlet implements SignupService {public boolean performSignup(String username, String password, String userCaptcha) {HttpServletRequest request = getThreadLocalRequest();HttpSession session = request.getSession();Captcha captcha = (Captcha) session.getAttribute(Captcha.NAME);return captcha.isCorrect(userCaptcha);}
}

扩展SimpleCaptcha
最后一步是设置Servlet,该Servlet将生成显示给用户的图像。 通过创建从提供的SimpeCaptchaServlet类继承的类,可以轻松扩展SimpleCaptcha。 相关代码如下:

package com.javacodegeeks.captcha.server.servlet;import static nl.captcha.Captcha.NAME;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;import nl.captcha.Captcha;
import nl.captcha.backgrounds.GradiatedBackgroundProducer;
import nl.captcha.servlet.CaptchaServletUtil;
import nl.captcha.servlet.SimpleCaptchaServlet;public class ExtendedCaptchaServlet extends SimpleCaptchaServlet {private static final long serialVersionUID = 6560171562324177699L;@Overridepublic void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {HttpSession session = req.getSession();Captcha captcha = new Captcha.Builder(_width, _height).addText().addBackground(new GradiatedBackgroundProducer()).gimp().addNoise().addBorder().build();session.setAttribute(NAME, captcha);CaptchaServletUtil.writeImage(resp, captcha.getImage());}}

作为初始化参数传递并从父类读取的“ _width”和“ _height”变量。 为了创建一个新的Captcha对象,我们使用Captcha.Builder类(依赖于构建器模式)。 然后,我们将对象传递到特定会话,并将关联的BufferedImage流传输到servlet响应。

请注意,我们的实现每次用户执行页面请求时都会生成一个新图像。 这与在给定会话中使用相同映像的默认SimpleCaptcha实现不同。

配置Web应用程序
所有组件都通过Web应用程序的“ web.xml”描述符捆绑在一起,在我们的示例中,描述符如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><web-app><!-- Default page to serve --><welcome-file-list><welcome-file>CaptchaGwtProject.html</welcome-file></welcome-file-list><!-- Servlets --><servlet><servlet-name>signupServlet</servlet-name><servlet-class>com.javacodegeeks.captcha.server.SignupServiceImpl</servlet-class></servlet><servlet-mapping><servlet-name>signupServlet</servlet-name><url-pattern>/captchagwtproject/signup</url-pattern></servlet-mapping><servlet><servlet-name>SimpleCaptcha</servlet-name><servlet-class>com.javacodegeeks.captcha.server.servlet.ExtendedCaptchaServlet</servlet-class><init-param><param-name>width</param-name><param-value>200</param-value></init-param><init-param><param-name>height</param-name><param-value>50</param-value></init-param></servlet><servlet-mapping><servlet-name>SimpleCaptcha</servlet-name><url-pattern>/SimpleCaptcha.jpg</url-pattern></servlet-mapping></web-app>

我们声明GWT服务(类“ SignupServiceImpl”)和欢迎文件。 这里没什么特别的。 最后,我们声明将负责图像生成并在“'/SimpleCaptcha.jpg”URL下处理请求的servlet(请记住,此请求在GWT入口点中使用)。 我们还为servlet提供了初始化参数(宽度和高度)。

而已! 运行该项目,您应该看到类似以下内容的内容:

每次刷新页面时,都会创建一个新的CAPTCHA映像。 单击“注册”按钮后,字段内容将发送到服务器,在服务器上用户提供的CAPTCHA值将针对当前会话中存在的值进行测试。 如果发生故障,我们将看到:


而已。 现在,您的应用程序可以更安全一些。

您可以在此处找到完整的Eclipse项目。

更新:一位读者询问是否可以添加“重新加载图像”功能。 确实有可能,但是从服务器重新获取图像时必须小心。 如以下讨论所述,浏览器将不会重新获取图像(因为它具有相同的URL)。 诀窍是添加一个虚拟参数,该参数将在每次刷新时更改。 在这里看看文章:

http://groups.google.gy/group/google-web-toolkit/browse_thread/thread/be9f1da56b5b1c18

事实是,我创建了该项目的新版本,可以在此处获取(按双关目标)。

请享用!

相关文章 :
  • 使用Spring Security保护GWT应用程序的安全
  • GWT 2 Spring 3 JPA 2 Hibernate 3.5教程– Eclipse和Maven 2展示
  • 建立自己的GWT Spring Maven原型
  • GWT EJB3 Maven JBoss 5.1集成教程

翻译自: https://www.javacodegeeks.com/2010/06/add-captcha-gwt-application.html

captcha库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/359469.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GCD6: 在GCD上异步执行非UI相关任务

讨论&#xff1a;在主队列、串行队列和并发队列上异步执行代码块才能见识到 GCD 的真正实力。 要在分派队列上执行异步任务,你必须使用下面这些函数中的其中一个: dispatch_async为了异步执行向分派队列提交一个 Block Object(2 项都通过参数指定) dispatch_async_f为了异步执行…

带有Java 8,lambda表达式和Mockito-Java8附加组件的更紧凑的Mockito

Mockito-Java8是一组Mockito附加组件&#xff0c;它们利用Java 8和lambda表达式使Mockito的模拟更加紧凑。 在2015年初&#xff0c;我进行了简短的演讲&#xff0c; Java 8为测试带来了力量&#xff01; 我在GeeCON TDD 2015和DevConf.cz 2015上发表了演讲。在我使用4个示例的演…

ContentProvider与ContentResolver使用

例如以下内容为从网络转载&#xff1a;使用ContentProvider共享数据&#xff1a;当应用继承ContentProvider类&#xff0c;并重写该类用于提供数据和存储数据的方法&#xff0c;就能够向其它应用共享其数据。虽然使用其它方法也能够对外共享数据&#xff0c;但数据訪问方式会因…

cshtml中引用css_ASP.NET CoreMVC 中的控制器

Controller in ASP.NET Core MVC在本节中&#xff0c;我们将讨论 Controller 是什么以及它在 ASP.NET Core MVC 中的作用。Fiddler需要大家提前装一个工具&#xff0c;https://www.telerik.com/fiddlerFiddler 是一个 http 协议调试代理工具&#xff0c;它能够记录并检查所有你…

小学阅读方法六种_小学生掌握了这些语文答题方法,轻松应对阅读理解,不再是难事...

家长们都知道&#xff0c;孩子们在学习数学的时候&#xff0c;重要的就是数学的一些公式&#xff0c;只要把数学公式记牢&#xff0c;做很多题的时候灵活运用&#xff0c;就可以解答。今天我们来看看&#xff0c;语文方面也有一些答题公式&#xff0c;当孩子们完全掌握了这些公…

hdu--4028--dp

这个dp我没做出来啊...其实不难..主要题意没理解好 fuck. 给你1-N这N个数 一共2^N-1个子集 每个子集的LCM值>M的情况数有多少种 我也是醉了 这么个题目 给我套他那个题面 硬是没看懂 他在问什么 还是 英语太渣了 然后就是个 状态转移方程的考虑了 map<LL,LL>dp[size]…

敏捷中gwt含义_在您的GWT应用程序中添加JSON功能

敏捷中gwt含义JSON简介 在Web应用程序上工作时&#xff0c;总是会出现客户端-服务器数据交换的问题。 在此问题上有多种方法&#xff0c;其中许多使用XML进行交换。 执行此任务的一种不太知名的格式是JSON。 JSON&#xff08;JavaScript对象表示法&#xff09;是一种轻量级的数…

c++ 经典代码_C语言经典100题(31)

1上期答案揭晓首先给大家看看上一篇文章C语言经典100题(30)中第三部分编程题的答案&#xff1a;#include int main( ){ long ge,shi,qian,wan,x; printf("请输入 5 位数字&#xff1a;"); scanf("%ld",&x); wanx/10000; /*分解出万…

$ 与 # 区别

# 会根据不同类型而生产字符串&#xff0c;如 String 类型 : aa ---> aa,长整型Long:123 ---> 123$ 表示原生类型&#xff0c;如 String 类型 : aa ---> aa,长整型Long:123 ---> 123转载于:https://www.cnblogs.com/svennee/p/4078824.html

JAX-RS 2.x与Spring MVC:返回对象列表的XML表示

JSON是所有REST * API的王者&#xff0c;但是您仍然可能需要公开多种表示形式&#xff0c;包括XML。 使用JAX-RS和Spring MVC都非常简单。 实际上&#xff0c;唯一要做的就是用JAXB注释对从API调用返回的POJO进行注释。 但是&#xff0c;我认为序列化对象列表时&#xff0c;JA…

android读取excel文件_python里读写excel等数据文件的几种常用方式

python处理数据文件第一步是要读取数据&#xff0c;文件类型主要包括文本文件(csv、txt等)、excel文件、数据库文件、api等。下面整理下python有哪些方式可以读取数据文件。1. python内置方法(read、readline、readlines)read() &#xff1a; 一次性读取整个文件内容。推荐使用…

UGUI学习笔记之渲染顺序

转载请注明地址&#xff1a;http://www.cnblogs.com/Vincentblogs/p/4083028.html QQ群&#xff1a;346738352 Unity技术交流群&#xff0c;讲纯粹的技术。 数据记录为Unity4.6b21版本 图片解释&#xff1a;这是一个按钮UI,层级1显示的是按钮背景&#xff0c;层级2显示的Image…

exp导出excel oracle_如何从Oracle快速导出数据到Excel

【摘要】在生产系统使用过程中&#xff0c;常常会有从数据库中导出数据的需求。支持多种导出方式&#xff0c;例如使用spool、utl_file等内置方法导出&#xff0c;利用plsql developer、等第三方工具等。【正文】Oracle支持多种导出方式&#xff0c;包括自带的工具包和第三方工…

C#找出数组中重复次数最多的数值

给定一个int数组&#xff0c;里面存在重复的数值&#xff0c;如何找到重复次数最多的数值呢? 这是在某社区上有人提出的问题&#xff0c;我想到的解决方法是分组。 1、先对数组中的所有元素进行分组&#xff0c;那么&#xff0c;重复的数值肯定会被放到一组中&#xff1b; 2、…

什么比日期和时区更难? SQL / JDBC中的日期和时区!

在jOOQ邮件列表上&#xff0c;最近有一个有趣的讨论&#xff0c;关于jOOQ当前缺乏对TIMESTAMP WITH TIME ZONE数据类型的现成支持。 没有人说日期&#xff0c;时间和时区很容易&#xff01; 这里有一个有趣的部分&#xff0c;我建议阅读&#xff1a; 虚假的程序员相信时间 当…

Javascript – 正则表达式

目录 1. 正则表达式1.1 创建1.2 RegExp 对象属性1.3 RegExp 对象方法1.4 RegExp 分组2. 元字符和正则表达式规则1正则表达式 正则表达式本身就是一种语言&#xff0c;由普通字符和特殊的元字符&#xff08;metacharacters&#xff09;组成。它描述了字符串的匹配模式&#xff0…

spark-sql建表语句限制_第三篇|Spark SQL编程指南

在《第二篇|Spark Core编程指南》一文中&#xff0c;对Spark的核心模块进行了讲解。本文将讨论Spark的另外一个重要模块--Spark SQL&#xff0c;Spark SQL是在Shark的基础之上构建的&#xff0c;于2014年5月发布。从名称上可以看出&#xff0c;该模块是Spark提供的关系型操作AP…

4固定在底部_礼堂椅厂家教你如何固定座椅

礼堂椅厂家众所周知&#xff0c;当人们离开时&#xff0c;礼堂或刷房中使用的座椅会自动翻转到垂直位置&#xff0c;因此行和行之间有一条大通道让人走路。 在现有技术中&#xff0c;通过以下方法翻转礼堂椅&#xff1a;在两个支腿之间设置固定轴&#xff0c;并且在支座底部的两…

带有Hibernate OGM的NoSQL –第三部分:在WildFly上构建REST应用程序

欢迎回到我们的教程系列“带有Hibernate OGM的NoSQL”&#xff01; 感谢Gunnar Morling&#xff08; gunnarmorling &#xff09;创建了本教程。 在这一部分中&#xff0c;您将学习如何在WildFly服务器上运行的Java EE应用程序中使用Hibernate OGM。 使用本教程前面部分已经知道…

关于创业公司的一些事情

最近终于离职了&#xff0c;离开了这家呆了快两年的公司&#xff0c;其中酸甜苦辣&#xff0c;不足为外人道&#xff0c;仅此记录下一些想法&#xff0c;供自己与大家思考。本文只讨论加入创业公司&#xff0c;并不讨论自己创业或者成为合伙人。 0. 该不该加入创业公司 我刚从研…