Its funny how my mind works – I was listening to NPR's Weekend Edition over the weekend and they were going through listener's comments. At the end of that segment, they mentioned that they were not going to accept email comments to their old address. They want listeners to go to npr.org and fill out a web form to enter their comments. The first thought I had was spam – It had to be spam. Having an open email address that's published must get a ton of spam. I know I get a ton of spam daily and so I'm guessing NPR must have been getting thousands and thousands of spam messages.
So as I'm driving along, I started thinking about moving to the web-form model to solicit feedback and I just assumed that they would take the next logical step and add Captcha to their web app. If you don't know, Captcha (completely automated public Turing test to tell computers and humans apart) is an acronym for a type of challenge-response test to determine whether or not the user is human. Thinking about Captcha got me thinking about JCaptcha, an open-source Java framework for Captcha definition and integration. I knew about JCaptcha as I had read about it on Dion's blog a while back and so I finally decided to download and give JCaptcha a try.
I was impressed with how easy it was to incorporate Captcha into an existing application. Here is a simple web-app I built using the 5 minutes application integration tutorial on the JCaptcha wiki.
Here's the JSP that acts as an entry into the application:
Sample JCaptcha
A captcha (an acronym for "
completely
automated
public
Turing test to tell
computers and
humans
apart") is a type of challenge-response test used in computing to determine whether or not the user is human.
To initialize the Captcha service, you create a singleton to instantiates an instance of the ImageCaptchaService that provides the facility to cache the Captcha and create the image.
package com.j2eegeek.jcaptcha.common;
import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;
import com.octo.captcha.service.image.ImageCaptchaService;
/**
* The CaptchaServiceSingleton implements the Singleton patterns and returns an instance of the
* ImageCaptchaService.
*/
public class CaptchaServiceSingleton {
private static ImageCaptchaService instance = new DefaultManageableImageCaptchaService();
public static ImageCaptchaService getInstance() {
return instance;
}
}
Once we've created an instance of the ImageCaptchaService, we can create a servlet that will allow us to create an image. The servlet ends up calling the singleton to get an instance of the CaptchaService Singleton and calling its getChallenge() method.
/**
* The ImageCaptchaServlet class creates the actual image that's displayed to the user for validation.
* The servlet ends up calling the singelton to get an instance of the CaptchaService Singleton and calling its
* getChallenge method.
*/
public class ImageCaptchaServlet extends J2EEGeekBaseServlet {
private static final Log log = LogFactory.getLog(ImageCaptchaServlet.class);
public void doWork(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
byte[] captchaChallengeAsJpeg = null;
// the output stream to render the captcha image as jpeg into
ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
try {
// get the session id that will identify the generated captcha.
String captchaId = req.getSession().getId();
// call the ImageCaptchaService getChallenge method
BufferedImage challenge = CaptchaServiceSingleton.getInstance().getImageChallengeForID(captchaId, req.getLocale());
// a jpeg encoder
JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(jpegOutputStream);
jpegEncoder.encode(challenge);
} catch (IllegalArgumentException e) {
log.error("IllegalArgumentException exception - " + e.getCause().getMessage());
res.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
} catch (CaptchaServiceException e) {
log.error("CaptchaServiceException exception - " + e.getCause().getMessage());
res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
// flush it in the response
res.setHeader("Cache-Control", "no-store");
res.setHeader("Pragma", "no-cache");
res.setDateHeader("Expires", 0);
res.setContentType("image/jpeg");
ServletOutputStream out = res.getOutputStream();
out.write(captchaChallengeAsJpeg);
out.flush();
out.close();
}
}
Once you've created the image and displayed it via the index.jsp page, you need to validate the response entered by the user.
public class ValidateServlet extends J2EEGeekBaseServlet {
private static final Log log = LogFactory.getLog(ValidateServlet.class);
public void doWork(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
res.setContentType("text/html");
ServletOutputStream out = res.getOutputStream();
out.println("
"); Boolean isResponseCorrect = Boolean.FALSE; String captchaId = req.getSession().getId(); String response = req.getParameter("j_captcha_response"); try { isResponseCorrect = CaptchaServiceSingleton.getInstance().validateResponseForID(captchaId, response); } catch (CaptchaServiceException e) { log.error("Exception - " + e.getCause().getMessage()); } if (isResponseCorrect.booleanValue()) { out.println("
"); } else { out.println("
Failure -- Try again"); } } }
Here's all the code that's essentially a rip-off from the wiki as a IDEA project. Another great resource is the JavaWorld article that Dion points to written by Anand Raman. He goes into details about incorporating Captcha into JAAS.
No tag for this post.
Related posts
No related posts.
June 4, 2005
Looks like what started out as a rumor might actually turn out to be true – C|Net is reporting that Apple Computer plans to announce Monday that it's scrapping its partnership with IBM and switching its computers to Intel's microprocessors. This is quite a shift for Apple but nothing new given their history of not worrying about backwards compatibility.
Now why would Apple want to switch to Intel chips? Would Apple actually sell their OS to the masses without their proprietary hardware? Could you just deploy the MAC OS on any vanilla Wintel machine? If that is their intention, it could potentially open up a huge market and revenue stream for Apple. It's interesting to look at a company like Microsoft who makes all of their money on software, running on commodity hardware. Hardware companies have had a much harder in the past 2 decades and so Apple could actually grow if they start thinking of themselves as a software company. I wonder what Microsoft thinks about this – Linux on the desktop for the masses has never been a viable option. I've been a Linux user since the early 90's but I've relegated my Linux boxes to the server role. If MAC OS was generally available for any Intel based machine, Windows would finally have some real competition for the desktop.
The article goes on to say that the higher-end Mac's would be running Intel chips in mid-2007, which is right around when Longhorn will probably ship. I guess this could end up being a great OS battle. The latest OS from Microsoft vs. the latest OS from Apple – I don't know how will win or even what will happen but I think consumers will win in the end because Microsoft will finally had to start innovating. Microsoft will have real competition in the OS market and they know that if you lose the OS market, you're going to lose the desktop and that usually means 'game over'. It's like the old Chinese proverb – "May you live in interesting times".
Of course this is all supposition as Apple could just be happy with the market share it currently has and the move to Intel could just something internal. But it seems like that this architecture change is pretty radical and there has to be something more to it.
No tag for this post.
Related posts
No related posts.