超棒的验证码生成组件---Jcaptcha
2010-01-12 09:34
393 查看
最近由于Springside3的发布,也来凑热闹学习学习, 毕竟是国人的开源项目。 由于之前仅仅有听过,但是没有具体研究,所以算比较落后的。 不过这个项目确实是非常好的项目, 从中可以了解不少新新东西( -
可能是我太过时了!)
正好我最近需要给老婆开发个小东西,其中有用到验证码的生成, 在Springside里面找到个非常棒的组件---Jcaptcha
Springside对其做了封装,而且其官方的文档看起来也比较费力。所以自己琢磨了半天,才学会一个小的demo。
这里发上来, 希望能帮助有需要的人, (本人在网上找了不少资料, 所给的素材不是不全就是说的不太明白)
OK,开始,我先从一个示例开始。
首先来看看示例的目录结构:
在Jcaptcha的官方文档中有一个 5分钟快速入门的文章, 是介绍快速开发的文章。 有兴趣的可以去上面看看。
这里我发上我的源代码:
web.xml中:
Xml代码
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<
web-app
>
<
servlet
>
<
servlet-name
>
jcaptcha
</
servlet-name
>
<
servlet-class
>
com.ivan.zhang.servlet.ImageCaptchaServlet
</
servlet-class
>
<
load-on-startup
>
0
</
load-on-startup
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>
jcaptcha
</
servlet-name
>
<
url-pattern
>
/jcaptcha
</
url-pattern
>
</
servlet-mapping
>
</
web-app
>
再需要一个服务类,用来产生Image Service类:
Java代码
package
com.ivan.zhang.servlet;
import
java.awt.image.BufferedImage;
import
java.io.ByteArrayOutputStream;
import
java.io.IOException;
import
javax.imageio.ImageIO;
import
javax.servlet.ServletConfig;
import
javax.servlet.ServletException;
import
javax.servlet.ServletOutputStream;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
com.ivan.zhang.CaptchaServiceSingleton;
import
com.octo.captcha.service.CaptchaServiceException;
import
com.sun.image.codec.jpeg.JPEGCodec;
import
com.sun.image.codec.jpeg.JPEGImageEncoder;
public
class
ImageCaptchaServlet
extends
HttpServlet {
/**
*
*/
private
static
final
long
serialVersionUID = 1L;
public
void
init(ServletConfig servletConfig)
throws
ServletException {
super
.init(servletConfig);
}
protected
void
doGet(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) 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.
// the same id must be used to validate the response, the session id
// is a good candidate!
String captchaId = httpServletRequest.getSession().getId();
// call the ImageCaptchaService getChallenge method
BufferedImage challenge = CaptchaServiceSingleton.getInstance()
.getImageChallengeForID(captchaId,
httpServletRequest.getLocale());
// a jpeg encoder
JPEGImageEncoder jpegEncoder = JPEGCodec
.createJPEGEncoder(jpegOutputStream);
jpegEncoder.encode(challenge);
} catch
(IllegalArgumentException e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return
;
} catch
(CaptchaServiceException e) {
httpServletResponse
.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return
;
}
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
// flush it in the response
httpServletResponse.setHeader("Cache-Control"
,
"no-store"
);
httpServletResponse.setHeader("Pragma"
,
"no-cache"
);
httpServletResponse.setDateHeader("Expires"
,
0
);
httpServletResponse.setContentType("image/jpeg"
);
ServletOutputStream responseOutputStream = httpServletResponse
.getOutputStream();
responseOutputStream.write(captchaChallengeAsJpeg);
responseOutputStream.flush();
responseOutputStream.close();
}
}
OK,后台的类写完了, 现在我们来看看前台页面的编写:
index.jsp
Java代码
<%@ page language=
"java"
contentType=
"text/html; charset=ISO-8859-1"
pageEncoding="UTF-8"
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"
>
<html>
<head>
<meta http-equiv="Content-Type"
content=
"text/html; charset=UTF-8"
>
<title>Insert title here</title>
</head>
<body>
<form action="sample.jsp"
>
<img src="jcaptcha"
>
<input type='text'
name=
'j_captcha_response'
value=
''
>
</form>
</body>
</html>
sample.jsp: (用来验证的页面
)
Java代码
<%@ page language=
"java"
contentType=
"text/html; charset=ISO-8859-1"
pageEncoding="UTF-8"
%>
<%@page
import
=
"com.octo.captcha.service.CaptchaServiceException"
%>
<%@page
import
=
"com.ivan.zhang.CaptchaServiceSingleton"
%>
<%
Boolean isResponseCorrect = Boolean.FALSE;
//remenber that we need an id to validate!
String captchaId = request.getSession().getId();
//retrieve the response
String responsestr = request.getParameter("j_captcha_response"
);
// Call the Service method
try
{
isResponseCorrect = CaptchaServiceSingleton.getInstance().validateResponseForID(captchaId, responsestr);
if
(isResponseCorrect){
}else
{
out.print("It's worng......"
);
}
} catch
(CaptchaServiceException e) {
//should not happen, may be thrown if the id is not valid
}
%>
这样,我们的第一个版本出来了, 我们来看看效果:
我们看到, 虽然生成了验证码,但是这样的图片给人非常不友好的感觉, 所以我参考Springside中的一样,自己给他设定产生图片的样式:
要实现自定义样式,我们需要一下2个步骤:
1. 告诉Jcaptcha 我要的样式是什么样子.
2. 在提交后,利用我们自己的样式来产生图片.
所以,我们改动一下 :
新加一个类GmailEngine.java(直接拿至Springside ,非常感谢白衣的共享,让我们这样的菜鸟学到很多东西.)
其中代码如下:
Java代码
package
com.ivan.zhang.servlet;
import
java.awt.Color;
import
java.awt.Font;
import
java.awt.image.ImageFilter;
import
com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
import
com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator;
import
com.octo.captcha.component.image.color.RandomListColorGenerator;
import
com.octo.captcha.component.image.deformation.ImageDeformation;
import
com.octo.captcha.component.image.deformation.ImageDeformationByFilters;
import
com.octo.captcha.component.image.fontgenerator.FontGenerator;
import
com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import
com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;
import
com.octo.captcha.component.image.textpaster.TextPaster;
import
com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator;
import
com.octo.captcha.component.image.wordtoimage.DeformedComposedWordToImage;
import
com.octo.captcha.component.image.wordtoimage.WordToImage;
import
com.octo.captcha.component.word.FileDictionary;
import
com.octo.captcha.component.word.wordgenerator.ComposeDictionaryWordGenerator;
import
com.octo.captcha.component.word.wordgenerator.WordGenerator;
import
com.octo.captcha.engine.image.ListImageCaptchaEngine;
import
com.octo.captcha.image.gimpy.GimpyFactory;
/**
* 仿照JCaptcha2.0编写GMail验证码样式的图片引擎.
*
* @author calvin
*/
public
class
GMailEngine
extends
ListImageCaptchaEngine {
@Override
protected
void
buildInitialFactories() {
int
minWordLength =
4
;
int
maxWordLength =
5
;
int
fontSize =
50
;
int
imageWidth =
250
;
int
imageHeight =
100
;
//word generator
WordGenerator dictionnaryWords = new
ComposeDictionaryWordGenerator(
new
FileDictionary(
"toddlist"
));
//word2image components
TextPaster randomPaster = new
DecoratedRandomTextPaster(minWordLength, maxWordLength,
new
RandomListColorGenerator(
new
Color[] {
new
Color(
23
,
170
,
27
),
new
Color(
220
,
34
,
11
),
new
Color(
23
,
67
,
172
) }),
new
TextDecorator[] {});
BackgroundGenerator background = new
UniColorBackgroundGenerator(imageWidth, imageHeight, Color.white);
FontGenerator font = new
RandomFontGenerator(fontSize, fontSize,
new
Font[] {
new
Font(
"nyala"
, Font.BOLD, fontSize),
new
Font(
"Bell MT"
, Font.PLAIN, fontSize),
new
Font(
"Credit valley"
, Font.BOLD, fontSize) });
ImageDeformation postDef = new
ImageDeformationByFilters(
new
ImageFilter[] {});
ImageDeformation backDef = new
ImageDeformationByFilters(
new
ImageFilter[] {});
ImageDeformation textDef = new
ImageDeformationByFilters(
new
ImageFilter[] {});
WordToImage word2image = new
DeformedComposedWordToImage(font, background, randomPaster, backDef, textDef,
postDef);
addFactory(new
GimpyFactory(dictionnaryWords, word2image));
}
}
如果有玩过Swing的兄弟,应该会很好理解上面的代码。
继续,我们有了自己的样式类, 接下来我们就要告诉servlet我们需要用哪个样式生成图片。
就有如下,将CaptchaServiceSingleton类修改一下:
Java代码
package
com.ivan.zhang;
import
com.ivan.zhang.servlet.GMailEngine;
import
com.octo.captcha.engine.GenericCaptchaEngine;
import
com.octo.captcha.service.CaptchaService;
import
com.octo.captcha.service.captchastore.FastHashMapCaptchaStore;
import
com.octo.captcha.service.image.DefaultManageableImageCaptchaService;
import
com.octo.captcha.service.image.ImageCaptchaService;
/**
* 按照官方的做法: 一定为单例
* @author Administrator
*
*/
public
class
CaptchaServiceSingleton {
private
static
ImageCaptchaService instance =
new
DefaultManageableImageCaptchaService(
new
FastHashMapCaptchaStore(),
new
GMailEngine(),
180
,
100000
,
75000
);
public
static
ImageCaptchaService getInstance(){
return
instance;
}
}
同样的,修改一下Servlet类:
改动如下:
Java代码
package
com.ivan.zhang.servlet;
import
java.awt.image.BufferedImage;
import
java.io.ByteArrayOutputStream;
import
java.io.IOException;
import
javax.imageio.ImageIO;
import
javax.servlet.ServletConfig;
import
javax.servlet.ServletException;
import
javax.servlet.ServletOutputStream;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
com.ivan.zhang.CaptchaServiceSingleton;
import
com.octo.captcha.service.CaptchaServiceException;
import
com.sun.image.codec.jpeg.JPEGCodec;
import
com.sun.image.codec.jpeg.JPEGImageEncoder;
public
class
ImageCaptchaServlet
extends
HttpServlet {
/**
*
*/
private
static
final
long
serialVersionUID = 1L;
public
void
init(ServletConfig servletConfig)
throws
ServletException {
super
.init(servletConfig);
}
protected
void
doGet(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws
ServletException,
IOException {
genernateCaptchaImage(httpServletRequest, httpServletResponse);
}
/**
* 生成验证码图片.
*/
private
void
genernateCaptchaImage(
final
HttpServletRequest request,
final
HttpServletResponse response)
throws
IOException {
response.setHeader("Cache-Control"
,
"no-store"
);
response.setHeader("Pragma"
,
"no-cache"
);
response.setDateHeader("Expires"
,
0
);
response.setContentType("image/jpeg"
);
ServletOutputStream out = response.getOutputStream();
try
{
String captchaId = request.getSession(true
).getId();
BufferedImage challenge = (BufferedImage) CaptchaServiceSingleton.getInstance().getChallengeForID(captchaId, request.getLocale());
ImageIO.write(challenge, "jpg"
, out);
out.flush();
} catch
(CaptchaServiceException e) {
} finally
{
out.close();
}
}
}
OK, 这样我们产生的图片样式就会好看多了。 不相信? OK, 非要上图才有人相信。
截图如下:
再来一下刷新:
OK, 先写到这,希望对有需要的人有帮助。
如果有人懒得敲代码,我这里附上我的工程源代码, 不过我还是觉得,咱弄技术的人, 就得把键盘当筷子, 你见过非常饿,但不想拿筷子的人吗?(别说老外用叉子……)
可能是我太过时了!)
正好我最近需要给老婆开发个小东西,其中有用到验证码的生成, 在Springside里面找到个非常棒的组件---Jcaptcha
Springside对其做了封装,而且其官方的文档看起来也比较费力。所以自己琢磨了半天,才学会一个小的demo。
这里发上来, 希望能帮助有需要的人, (本人在网上找了不少资料, 所给的素材不是不全就是说的不太明白)
OK,开始,我先从一个示例开始。
首先来看看示例的目录结构:
在Jcaptcha的官方文档中有一个 5分钟快速入门的文章, 是介绍快速开发的文章。 有兴趣的可以去上面看看。
这里我发上我的源代码:
web.xml中:
Xml代码
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<
web-app
>
<
servlet
>
<
servlet-name
>
jcaptcha
</
servlet-name
>
<
servlet-class
>
com.ivan.zhang.servlet.ImageCaptchaServlet
</
servlet-class
>
<
load-on-startup
>
0
</
load-on-startup
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>
jcaptcha
</
servlet-name
>
<
url-pattern
>
/jcaptcha
</
url-pattern
>
</
servlet-mapping
>
</
web-app
>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>jcaptcha</servlet-name> <servlet-class>com.ivan.zhang.servlet.ImageCaptchaServlet</servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jcaptcha</servlet-name> <url-pattern>/jcaptcha</url-pattern> </servlet-mapping> </web-app>
再需要一个服务类,用来产生Image Service类:
Java代码
package
com.ivan.zhang.servlet;
import
java.awt.image.BufferedImage;
import
java.io.ByteArrayOutputStream;
import
java.io.IOException;
import
javax.imageio.ImageIO;
import
javax.servlet.ServletConfig;
import
javax.servlet.ServletException;
import
javax.servlet.ServletOutputStream;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
com.ivan.zhang.CaptchaServiceSingleton;
import
com.octo.captcha.service.CaptchaServiceException;
import
com.sun.image.codec.jpeg.JPEGCodec;
import
com.sun.image.codec.jpeg.JPEGImageEncoder;
public
class
ImageCaptchaServlet
extends
HttpServlet {
/**
*
*/
private
static
final
long
serialVersionUID = 1L;
public
void
init(ServletConfig servletConfig)
throws
ServletException {
super
.init(servletConfig);
}
protected
void
doGet(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) 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.
// the same id must be used to validate the response, the session id
// is a good candidate!
String captchaId = httpServletRequest.getSession().getId();
// call the ImageCaptchaService getChallenge method
BufferedImage challenge = CaptchaServiceSingleton.getInstance()
.getImageChallengeForID(captchaId,
httpServletRequest.getLocale());
// a jpeg encoder
JPEGImageEncoder jpegEncoder = JPEGCodec
.createJPEGEncoder(jpegOutputStream);
jpegEncoder.encode(challenge);
} catch
(IllegalArgumentException e) {
httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND);
return
;
} catch
(CaptchaServiceException e) {
httpServletResponse
.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return
;
}
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
// flush it in the response
httpServletResponse.setHeader("Cache-Control"
,
"no-store"
);
httpServletResponse.setHeader("Pragma"
,
"no-cache"
);
httpServletResponse.setDateHeader("Expires"
,
0
);
httpServletResponse.setContentType("image/jpeg"
);
ServletOutputStream responseOutputStream = httpServletResponse
.getOutputStream();
responseOutputStream.write(captchaChallengeAsJpeg);
responseOutputStream.flush();
responseOutputStream.close();
}
}
package com.ivan.zhang.servlet; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ivan.zhang.CaptchaServiceSingleton; import com.octo.captcha.service.CaptchaServiceException; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class ImageCaptchaServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); } protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) 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. // the same id must be used to validate the response, the session id // is a good candidate! String captchaId = httpServletRequest.getSession().getId(); // call the ImageCaptchaService getChallenge method BufferedImage challenge = CaptchaServiceSingleton.getInstance() .getImageChallengeForID(captchaId, httpServletRequest.getLocale()); // a jpeg encoder JPEGImageEncoder jpegEncoder = JPEGCodec .createJPEGEncoder(jpegOutputStream); jpegEncoder.encode(challenge); } catch (IllegalArgumentException e) { httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND); return; } catch (CaptchaServiceException e) { httpServletResponse .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } captchaChallengeAsJpeg = jpegOutputStream.toByteArray(); // flush it in the response httpServletResponse.setHeader("Cache-Control", "no-store"); httpServletResponse.setHeader("Pragma", "no-cache"); httpServletResponse.setDateHeader("Expires", 0); httpServletResponse.setContentType("image/jpeg"); ServletOutputStream responseOutputStream = httpServletResponse .getOutputStream(); responseOutputStream.write(captchaChallengeAsJpeg); responseOutputStream.flush(); responseOutputStream.close(); } }
OK,后台的类写完了, 现在我们来看看前台页面的编写:
index.jsp
Java代码
<%@ page language=
"java"
contentType=
"text/html; charset=ISO-8859-1"
pageEncoding="UTF-8"
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"
>
<html>
<head>
<meta http-equiv="Content-Type"
content=
"text/html; charset=UTF-8"
>
<title>Insert title here</title>
</head>
<body>
<form action="sample.jsp"
>
<img src="jcaptcha"
>
<input type='text'
name=
'j_captcha_response'
value=
''
>
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="sample.jsp"> <img src="jcaptcha"> <input type='text' name='j_captcha_response' value=''> </form> </body> </html>
sample.jsp: (用来验证的页面
)
Java代码
<%@ page language=
"java"
contentType=
"text/html; charset=ISO-8859-1"
pageEncoding="UTF-8"
%>
<%@page
import
=
"com.octo.captcha.service.CaptchaServiceException"
%>
<%@page
import
=
"com.ivan.zhang.CaptchaServiceSingleton"
%>
<%
Boolean isResponseCorrect = Boolean.FALSE;
//remenber that we need an id to validate!
String captchaId = request.getSession().getId();
//retrieve the response
String responsestr = request.getParameter("j_captcha_response"
);
// Call the Service method
try
{
isResponseCorrect = CaptchaServiceSingleton.getInstance().validateResponseForID(captchaId, responsestr);
if
(isResponseCorrect){
}else
{
out.print("It's worng......"
);
}
} catch
(CaptchaServiceException e) {
//should not happen, may be thrown if the id is not valid
}
%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="UTF-8"%> <%@page import="com.octo.captcha.service.CaptchaServiceException"%> <%@page import="com.ivan.zhang.CaptchaServiceSingleton"%> <% Boolean isResponseCorrect = Boolean.FALSE; //remenber that we need an id to validate! String captchaId = request.getSession().getId(); //retrieve the response String responsestr = request.getParameter("j_captcha_response"); // Call the Service method try { isResponseCorrect = CaptchaServiceSingleton.getInstance().validateResponseForID(captchaId, responsestr); if(isResponseCorrect){ }else{ out.print("It's worng......"); } } catch (CaptchaServiceException e) { //should not happen, may be thrown if the id is not valid } %>
这样,我们的第一个版本出来了, 我们来看看效果:
我们看到, 虽然生成了验证码,但是这样的图片给人非常不友好的感觉, 所以我参考Springside中的一样,自己给他设定产生图片的样式:
要实现自定义样式,我们需要一下2个步骤:
1. 告诉Jcaptcha 我要的样式是什么样子.
2. 在提交后,利用我们自己的样式来产生图片.
所以,我们改动一下 :
新加一个类GmailEngine.java(直接拿至Springside ,非常感谢白衣的共享,让我们这样的菜鸟学到很多东西.)
其中代码如下:
Java代码
package
com.ivan.zhang.servlet;
import
java.awt.Color;
import
java.awt.Font;
import
java.awt.image.ImageFilter;
import
com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
import
com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator;
import
com.octo.captcha.component.image.color.RandomListColorGenerator;
import
com.octo.captcha.component.image.deformation.ImageDeformation;
import
com.octo.captcha.component.image.deformation.ImageDeformationByFilters;
import
com.octo.captcha.component.image.fontgenerator.FontGenerator;
import
com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import
com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;
import
com.octo.captcha.component.image.textpaster.TextPaster;
import
com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator;
import
com.octo.captcha.component.image.wordtoimage.DeformedComposedWordToImage;
import
com.octo.captcha.component.image.wordtoimage.WordToImage;
import
com.octo.captcha.component.word.FileDictionary;
import
com.octo.captcha.component.word.wordgenerator.ComposeDictionaryWordGenerator;
import
com.octo.captcha.component.word.wordgenerator.WordGenerator;
import
com.octo.captcha.engine.image.ListImageCaptchaEngine;
import
com.octo.captcha.image.gimpy.GimpyFactory;
/**
* 仿照JCaptcha2.0编写GMail验证码样式的图片引擎.
*
* @author calvin
*/
public
class
GMailEngine
extends
ListImageCaptchaEngine {
@Override
protected
void
buildInitialFactories() {
int
minWordLength =
4
;
int
maxWordLength =
5
;
int
fontSize =
50
;
int
imageWidth =
250
;
int
imageHeight =
100
;
//word generator
WordGenerator dictionnaryWords = new
ComposeDictionaryWordGenerator(
new
FileDictionary(
"toddlist"
));
//word2image components
TextPaster randomPaster = new
DecoratedRandomTextPaster(minWordLength, maxWordLength,
new
RandomListColorGenerator(
new
Color[] {
new
Color(
23
,
170
,
27
),
new
Color(
220
,
34
,
11
),
new
Color(
23
,
67
,
172
) }),
new
TextDecorator[] {});
BackgroundGenerator background = new
UniColorBackgroundGenerator(imageWidth, imageHeight, Color.white);
FontGenerator font = new
RandomFontGenerator(fontSize, fontSize,
new
Font[] {
new
Font(
"nyala"
, Font.BOLD, fontSize),
new
Font(
"Bell MT"
, Font.PLAIN, fontSize),
new
Font(
"Credit valley"
, Font.BOLD, fontSize) });
ImageDeformation postDef = new
ImageDeformationByFilters(
new
ImageFilter[] {});
ImageDeformation backDef = new
ImageDeformationByFilters(
new
ImageFilter[] {});
ImageDeformation textDef = new
ImageDeformationByFilters(
new
ImageFilter[] {});
WordToImage word2image = new
DeformedComposedWordToImage(font, background, randomPaster, backDef, textDef,
postDef);
addFactory(new
GimpyFactory(dictionnaryWords, word2image));
}
}
package com.ivan.zhang.servlet; import java.awt.Color; import java.awt.Font; import java.awt.image.ImageFilter; import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator; import com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator; import com.octo.captcha.component.image.color.RandomListColorGenerator; import com.octo.captcha.component.image.deformation.ImageDeformation; import com.octo.captcha.component.image.deformation.ImageDeformationByFilters; import com.octo.captcha.component.image.fontgenerator.FontGenerator; import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator; import com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster; import com.octo.captcha.component.image.textpaster.TextPaster; import com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator; import com.octo.captcha.component.image.wordtoimage.DeformedComposedWordToImage; import com.octo.captcha.component.image.wordtoimage.WordToImage; import com.octo.captcha.component.word.FileDictionary; import com.octo.captcha.component.word.wordgenerator.ComposeDictionaryWordGenerator; import com.octo.captcha.component.word.wordgenerator.WordGenerator; import com.octo.captcha.engine.image.ListImageCaptchaEngine; import com.octo.captcha.image.gimpy.GimpyFactory; /** * 仿照JCaptcha2.0编写GMail验证码样式的图片引擎. * * @author calvin */ public class GMailEngine extends ListImageCaptchaEngine { @Override protected void buildInitialFactories() { int minWordLength = 4; int maxWordLength = 5; int fontSize = 50; int imageWidth = 250; int imageHeight = 100; //word generator WordGenerator dictionnaryWords = new ComposeDictionaryWordGenerator(new FileDictionary("toddlist")); //word2image components TextPaster randomPaster = new DecoratedRandomTextPaster(minWordLength, maxWordLength, new RandomListColorGenerator(new Color[] { new Color(23, 170, 27), new Color(220, 34, 11), new Color(23, 67, 172) }), new TextDecorator[] {}); BackgroundGenerator background = new UniColorBackgroundGenerator(imageWidth, imageHeight, Color.white); FontGenerator font = new RandomFontGenerator(fontSize, fontSize, new Font[] { new Font("nyala", Font.BOLD, fontSize), new Font("Bell MT", Font.PLAIN, fontSize), new Font("Credit valley", Font.BOLD, fontSize) }); ImageDeformation postDef = new ImageDeformationByFilters(new ImageFilter[] {}); ImageDeformation backDef = new ImageDeformationByFilters(new ImageFilter[] {}); ImageDeformation textDef = new ImageDeformationByFilters(new ImageFilter[] {}); WordToImage word2image = new DeformedComposedWordToImage(font, background, randomPaster, backDef, textDef, postDef); addFactory(new GimpyFactory(dictionnaryWords, word2image)); } }
如果有玩过Swing的兄弟,应该会很好理解上面的代码。
继续,我们有了自己的样式类, 接下来我们就要告诉servlet我们需要用哪个样式生成图片。
就有如下,将CaptchaServiceSingleton类修改一下:
Java代码
package
com.ivan.zhang;
import
com.ivan.zhang.servlet.GMailEngine;
import
com.octo.captcha.engine.GenericCaptchaEngine;
import
com.octo.captcha.service.CaptchaService;
import
com.octo.captcha.service.captchastore.FastHashMapCaptchaStore;
import
com.octo.captcha.service.image.DefaultManageableImageCaptchaService;
import
com.octo.captcha.service.image.ImageCaptchaService;
/**
* 按照官方的做法: 一定为单例
* @author Administrator
*
*/
public
class
CaptchaServiceSingleton {
private
static
ImageCaptchaService instance =
new
DefaultManageableImageCaptchaService(
new
FastHashMapCaptchaStore(),
new
GMailEngine(),
180
,
100000
,
75000
);
public
static
ImageCaptchaService getInstance(){
return
instance;
}
}
package com.ivan.zhang; import com.ivan.zhang.servlet.GMailEngine; import com.octo.captcha.engine.GenericCaptchaEngine; import com.octo.captcha.service.CaptchaService; import com.octo.captcha.service.captchastore.FastHashMapCaptchaStore; import com.octo.captcha.service.image.DefaultManageableImageCaptchaService; import com.octo.captcha.service.image.ImageCaptchaService; /** * 按照官方的做法: 一定为单例 * @author Administrator * */ public class CaptchaServiceSingleton { private static ImageCaptchaService instance = new DefaultManageableImageCaptchaService( new FastHashMapCaptchaStore(), new GMailEngine(), 180, 100000 , 75000); public static ImageCaptchaService getInstance(){ return instance; } }
同样的,修改一下Servlet类:
改动如下:
Java代码
package
com.ivan.zhang.servlet;
import
java.awt.image.BufferedImage;
import
java.io.ByteArrayOutputStream;
import
java.io.IOException;
import
javax.imageio.ImageIO;
import
javax.servlet.ServletConfig;
import
javax.servlet.ServletException;
import
javax.servlet.ServletOutputStream;
import
javax.servlet.http.HttpServlet;
import
javax.servlet.http.HttpServletRequest;
import
javax.servlet.http.HttpServletResponse;
import
com.ivan.zhang.CaptchaServiceSingleton;
import
com.octo.captcha.service.CaptchaServiceException;
import
com.sun.image.codec.jpeg.JPEGCodec;
import
com.sun.image.codec.jpeg.JPEGImageEncoder;
public
class
ImageCaptchaServlet
extends
HttpServlet {
/**
*
*/
private
static
final
long
serialVersionUID = 1L;
public
void
init(ServletConfig servletConfig)
throws
ServletException {
super
.init(servletConfig);
}
protected
void
doGet(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws
ServletException,
IOException {
genernateCaptchaImage(httpServletRequest, httpServletResponse);
}
/**
* 生成验证码图片.
*/
private
void
genernateCaptchaImage(
final
HttpServletRequest request,
final
HttpServletResponse response)
throws
IOException {
response.setHeader("Cache-Control"
,
"no-store"
);
response.setHeader("Pragma"
,
"no-cache"
);
response.setDateHeader("Expires"
,
0
);
response.setContentType("image/jpeg"
);
ServletOutputStream out = response.getOutputStream();
try
{
String captchaId = request.getSession(true
).getId();
BufferedImage challenge = (BufferedImage) CaptchaServiceSingleton.getInstance().getChallengeForID(captchaId, request.getLocale());
ImageIO.write(challenge, "jpg"
, out);
out.flush();
} catch
(CaptchaServiceException e) {
} finally
{
out.close();
}
}
}
package com.ivan.zhang.servlet; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ivan.zhang.CaptchaServiceSingleton; import com.octo.captcha.service.CaptchaServiceException; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder; public class ImageCaptchaServlet extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); } protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException { genernateCaptchaImage(httpServletRequest, httpServletResponse); } /** * 生成验证码图片. */ private void genernateCaptchaImage(final HttpServletRequest request, final HttpServletResponse response) throws IOException { response.setHeader("Cache-Control", "no-store"); response.setHeader("Pragma", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); ServletOutputStream out = response.getOutputStream(); try { String captchaId = request.getSession(true).getId(); BufferedImage challenge = (BufferedImage) CaptchaServiceSingleton.getInstance().getChallengeForID(captchaId, request.getLocale()); ImageIO.write(challenge, "jpg", out); out.flush(); } catch (CaptchaServiceException e) { } finally { out.close(); } } }
OK, 这样我们产生的图片样式就会好看多了。 不相信? OK, 非要上图才有人相信。
截图如下:
再来一下刷新:
OK, 先写到这,希望对有需要的人有帮助。
如果有人懒得敲代码,我这里附上我的工程源代码, 不过我还是觉得,咱弄技术的人, 就得把键盘当筷子, 你见过非常饿,但不想拿筷子的人吗?(别说老外用叉子……)
相关文章推荐
- JCaptcha开源组件-生成第一个验证码
- 验证码生成组件--JCaptcha的使用
- 验证码生成组件--JCaptcha的使用
- 验证码生成组件--JCaptcha的使用
- 超棒的验证码生成组件---Jcaptcha
- 验证码生成组件--JCaptcha的使用
- 超棒的验证码生成组件---Jcaptcha
- 验证码生成组件--JCaptcha的使用
- 超棒的验证码生成组件---Jcaptcha
- jcaptcha验证码组件
- Java验证码生成库JCaptcha入门
- 浅析Java验证码生成库JCaptcha
- 无组件生成BMP验证码
- 无组件生成BMP验证码
- 无组件生成BMP验证码(转)
- java验证码组件Jcaptcha
- jcaptcha+ofbiz生成验证码
- java验证码组件Jcaptcha
- 用开源组件jcaptcha做jsp彩色验证码
- ASP生成验证码-BMP图片原理,GIF格式,无组件生成验证码