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

什么是验证码?
在一个充满恶意机器人的世界中,您该怎么做才能保护您宝贵的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

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

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

相关文章

SQL基础语句

数据库面试常见题 一、SQL语言包括数据定义语言、数据操作语言、数据控制语言和事务控制语言1&#xff1a;DDL(Data Definition Language)&#xff0c;是用于描述数据库中要存储的现实世界实体的语言。 CREATE TABLE - 创建新表 ALTER TABLE - 变更&#xff08;改变&#xff0…

iOS学习——ScrollView图片轮播和同类控件优先级问题

iOS学习——ScrollView的使用和同类控件优先级问题 1. 布置界面 ScrollView的使用非常简单&#xff0c;只有三步 1.1 添加一个scrollview 1.2 向scrollview添加内容 1.3 告诉scrollview中内容的实际大小 首先做第一步&#xff0c;布置界面。 拖拽一个scrollview就可以了 就…

Git 分支管理和冲突解决

创建分支 git branch 没有参数&#xff0c;显示本地版本库中所有的本地分支名称。 当前检出分支的前面会有星号。 git branch newname 在当前检出分支上新建分支&#xff0c;名叫newname。 git checkout newname 检出分支&#xff0c;即切换到名叫newname的分支。 git checkout…

git克隆/更新/提交代码步骤及示意图

1. git clone ssh://flycm.intel.com/scm/at/atSrc 或者git clone ssh://flycm.intel.com/scm/at/atJar 或者git clone ssh://flycm.intel.com/scm/at/atFramework 2. git checkout cpeg/scm/stable 切换分支&#xff0c;然后更新代码 3. git pull 先把远程分支上最新的代码拉到…

互联网金融P2P主业务场景自动化测试

互联网金融P2P行业&#xff0c;近三年来发展迅速&#xff0c;如火如荼。据不完全统计&#xff0c;全国有3000的企业。“互联网”企业&#xff0c;几乎每天都会碰到一些奇奇怪怪的bug&#xff0c;作为在互联网企业工作的测试人员&#xff0c;风险和压力都巨大。那么我们如何降低…

OSGi将Maven与Equinox结合使用

很长时间以来&#xff0c;我一直在努力理解OSGi的真正含义。 它已经存在很长时间了&#xff0c;但是没有多少人意识到这一点。 人们已经大肆宣传它是一种非常复杂的技术。 这是我为所有Java开发人员简化的尝试。 简而言之&#xff0c; OSGi是一组规范&#xff0c;这些规范允许对…

Hadoop:简单介绍

什么是Hadoop&#xff1a; Hadoop是一种用Java编写的框架&#xff0c;用于在大型商品硬件集群上运行应用程序&#xff0c;并具有类似于Google File System和MapReduce的功能 。 HDFS是高度容错的分布式文件系统&#xff0c;与Hadoop一样&#xff0c;旨在部署在低成本硬件上。 它…

Javascript 异步编程的4种方法

你可能知道&#xff0c;Javascript语言的执行环境是"单线程"&#xff08;single thread&#xff09;。 所谓"单线程"&#xff0c;就是指一次只能完成一件任务。如果有多个任务&#xff0c;就必须排队&#xff0c;前面一个任务完成&#xff0c;再执行后面一…

JAVA入门之方法

所谓方法&#xff0c;就是用来解决一类问题的代码的有序组合&#xff0c;是一个功能模块。 一般情况下&#xff0c;定义一个方法的语法是&#xff1a; 其中&#xff1a; 1、 访问修饰符&#xff1a;方法允许被访问的权限范围&#xff0c; 可以是 public、protected、private 甚…

JAVA运算符和优先级

1、算术运算符&#xff1a; 和 -- 既可以出现在操作数的左边&#xff0c;也可以出现在右边&#xff0c;但结果是不同&#xff0c;如&#xff1a; ①int a5&#xff1b;int ba&#xff1b; #先把a赋给b&#xff0c;a再自增 ②int a5&#xff1b;int ba&#xff1b;   #a先…

将JSON功能添加到您的GWT应用程序中

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

win10资源管理器怎么打开_让你效率倍增的电脑神器,最强资源管理器增强工具「QTTabBar」...

前言Windows 自带的资源管理器的功能比较简单&#xff0c;够用是够用了&#xff0c;但有时也确实无法满足我们对更便捷高效的操作方式的追求。「QTTabBar」正是一个非常强大的 Windows 资源管理器增强工具&#xff01;不仅支持多标签页管理&#xff0c;还有许多便捷的扩展功能&…

android横向滑动选择的view

做文字编辑&#xff0c;从网上找来的。 HorizontalScrollSelectView&#xff1a; public boolean mAlwaysOverrideTouch true;protected ListAdapter mAdapter;private int mLeftViewIndex -1;private int mRightViewIndex 0;protected int mCurrentX;protected int mNextX;…

excel使用教程_数据分析Excel必备技能:数据透视表使用教程

江米小枣tonylua | 作者掘金 | 来源处理数量较大的数据时&#xff0c;一般分为数据获取、数据筛选&#xff0c;以及结果展示几个步骤。在 Excel 中&#xff0c;我们可以利用数据透视表(Pivot Table)方便快捷的实现这些工作。本文首先手把手的教你如何在 Excel 中手动构建一个基…

java调用webservice_笃学私教:Java开发网站架构演变过程-从单体应用到微服务架构详解...

原标题&#xff1a;笃学私教&#xff1a;Java开发网站架构演变过程-从单体应用到微服务架构详解Java开发网站架构演变过程&#xff0c;到目前为止&#xff0c;大致分为5个阶段&#xff0c;分别为单体架构、集群架构、分布式架构、SOA架构和微服务架构。下面玄武老师来给大家详细…

专2-第二课 Eclipse开发环境搭建

2.1下载Eclipse 2.2 安装C/C版本的Eclipse 2.3 安装JDT插件开发Java程序 2.4 使用Eclipse开发驱动程序 既然安装了eclipse来进行驱动学习&#xff0c;那么我们就先来试试看eclipse开发驱动的大致流程。这里以Linux设备驱动作为示列给读者展示整个流程&#xff0c;Android底层的…

tkinter 菜单添加事件_Tasker的最新测试劫持了Android 11的电源菜单

流行的Android自动化应用Tasker 最近收到了重大更新&#xff0c;为该应用引入了许多新功能。该更新包括解锁应用程序读取手机上任何传感器以触发任务的功能&#xff0c;使您可以通过任何第三方应用程序自动发送短信或拨打电话的功能&#xff0c;完全请勿打扰自定义功能。通过链…

CLR via C#(18)——Enum

1. Enum定义 枚举类型是经常用的一种“名称/值”的形式&#xff0c;例如&#xff1a; public enum FeedbackStatus { New, Processing, Verify, Closed } 定义枚举类型之后我们在使用时方便了许多&#xff0c;不用再记着0代表什么状态…

电力电子、电机控制系统的建模和仿真_清华团队研发,首款国产电力电子仿真软件来啦~已捐赠哈工大、海工大、清华使用!...

点击上方电气小青年&#xff0c;关注并星标由于微信改版&#xff0c;只有星标才能及时看到我们的消息哦━━━━━━推荐阅读&#xff1a;《膜拜大神&#xff01;清华大学电机系2021年接收推荐免试直硕(博)生拟录取名单公示&#xff01;》《滴滴程序员年薪80万被鄙视不如在二本…

可视化分析之图表选择

转载于:https://www.cnblogs.com/yymn/p/4783631.html