Kaptcha和JCaptcha使用介绍

Kaptcha 简介

Kaptcha 是一个非常实用的验证码生成工具,它是基于SimpleCaptcha的开源项目。通过调整Kaptcha配置可以生成各种样式的验证码。

使用Kaptcha可以方便的配置以下细节:

  • 验证码的字体
  • 验证码字体的大小
  • 验证码字体的字体颜色
  • 验证码内容的范围
  • 验证码图片的大小,边框,边框粗细,边框颜色
  • 验证码的干扰线
  • 验证码的样式

JCaptcha简介

JCapthca是一个开源的用来生成图形验证码的Java开源组件,它非常强大,不光是可以生成图片式的验证码,还可以生成声音式的。

JCaptcha是CAPTCHA里面的一个比较著名的项目。

Kaptcha测试实例

添加依赖包

在pom.xml文件中新增dependency

1
2
3
4
5
<dependency>
<groupId>com.google.code.kaptcha</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3</version>
</dependency>

配置applicationContext.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
<property name="config">
<bean class="com.google.code.kaptcha.util.Config">
<constructor-arg>
<props>
<prop key="kaptcha.border">yes</prop>
<prop key="kaptcha.border.color">105,179,90</prop>
<prop key="kaptcha.textproducer.font.color">blue</prop>
<prop key="kaptcha.image.width">80</prop>
<prop key="kaptcha.image.height">30</prop>
<prop key="kaptcha.textproducer.font.size">27</prop>
<prop key="kaptcha.session.key">code</prop>
<prop key="kaptcha.textproducer.char.length">4</prop>
<prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop>
<prop key="kaptcha.textproducer.char.string">123456789ABCE</prop>
<prop key="kaptcha.obscurificator.impl">com.google.code.kaptcha.impl.WaterRipple</prop>
<prop key="kaptcha.noise.color">white</prop>
<prop key="kaptcha.noise.impl">com.google.code.kaptcha.impl.NoNoise</prop>
<prop key="kaptcha.background.clear.from">white</prop>
<prop key="kaptcha.background.clear.to">white</prop>
</props>
</constructor-arg>
</bean>
</property>
</bean>

Controller实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.util.Random;
@Controller
@RequestMapping("/code")
public class CaptchaController {
@Resource
private Producer captchaProducer;
@ResponseBody
@RequestMapping(value = "/captchaImage")
public void getKaptchaImage(HttpServletRequest request,HttpServletResponse response) throws Exception {
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/jpeg");
String capText = captchaProducer.createText();// 生成验证码字符串
Cookie cookie = new Cookie(Constants.KAPTCHA_SESSION_KEY, capText); // 生成cookie
cookie.setMaxAge(300); // 300秒生存期
response.addCookie(cookie); // 将cookie加入response
BufferedImage bi = captchaProducer.createImage(capText);// 生成验证码图片
ServletOutputStream out = response.getOutputStream();
ImageIO.write(bi, "jpg", out);
try {
out.flush();
} finally {
out.close();
}
return;
}
private String getRandomString(int length) {
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder(length + 1);
for (int i = 0; i < length; ++i) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
}

前端代码

1
<img id="verify" width="80" height="30" src="/code/captchaImage" />

测试结果

Kaptcha测试结果

Kaptcha可配置项

配置项 描述 默认值 可选值
kaptcha.border 是否有边框 默认为yes yes,no
kaptcha.border.color 边框颜色 默认为Color.BLACK
kaptcha.border.thickness 边框粗细度 默认为1
kaptcha.producer.impl 验证码生成器 默认为DefaultKaptcha
kaptcha.textproducer.impl 验证码文本生成器 默认为DefaultTextCreator
kaptcha.textproducer.char.string 验证码文本字符内容范围
kaptcha.textproducer.char.length 验证码文本字符长度 默认为5
kaptcha.textproducer.font.names 验证码文本字体样式
kaptcha.textproducer.font.size 验证码文本字符大小 默认为40
kaptcha.textproducer.font.color 验证码文本字符颜色 默认为Color.BLACK
kaptcha.textproducer.char.space 验证码文本字符间距 默认为2
kaptcha.noise.impl 验证码噪点生成对象 默认为DefaultNoise
kaptcha.noise.color 验证码噪点颜色 默认为Color.BLACK
kaptcha.obscurificator.impl 验证码样式引擎 默认为WaterRipple
kaptcha.word.impl 验证码文本字符渲染 默认为DefaultWordRenderer
kaptcha.background.impl 验证码背景生成器 默认为DefaultBackground
kaptcha.background.clear.from 验证码背景颜色渐进 默认为Color.LIGHT_GRAY
kaptcha.background.clear.to 验证码背景颜色渐进 默认为Color.WHITE
kaptcha.image.width 验证码图片宽度 默认为200
kaptcha.image.height 验证码图片高度 默认为50

图片样式:
水纹 com.google.code.kaptcha.impl.WaterRipple
鱼眼 com.google.code.kaptcha.impl.FishEyeGimpy
阴影 com.google.code.kaptcha.impl.ShadowGimpy

JCaptcha测试实例

添加依赖包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<dependency>
<groupId>com.octo.captcha</groupId>
<artifactId>jcaptcha-all</artifactId>
<version>1.0-RC6</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>

注意:如果是Spring项目,必须加上exclusion,不然会提示BeanDefinitionParsingException错误。

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate NamespaceHandler for namespace [http://www.springframework.org/schema/mvc]

Service实现

JCaptcha建议使用单例提供服务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import com.octo.captcha.component.image.backgroundgenerator.GradientBackgroundGenerator;
import com.octo.captcha.component.image.color.SingleColorGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.NonLinearTextPaster;
import com.octo.captcha.component.image.wordtoimage.ComposedWordToImage;
import com.octo.captcha.component.word.wordgenerator.RandomWordGenerator;
import com.octo.captcha.engine.GenericCaptchaEngine;
import com.octo.captcha.image.gimpy.GimpyFactory;
import com.octo.captcha.service.captchastore.FastHashMapCaptchaStore;
import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;
import com.octo.captcha.service.image.ImageCaptchaService;
import java.awt.*;
public class CaptchaService {
private static class SingletonHolder {
private static ImageCaptchaService imageCaptchaService = new DefaultManageableImageCaptchaService(
new FastHashMapCaptchaStore(),
new GenericCaptchaEngine(
new GimpyFactory[]{new GimpyFactory(
new RandomWordGenerator("123456789ABCE"),
new ComposedWordToImage(
new RandomFontGenerator(20, 20, new Font[]{new Font("Arial", 20, 20)}),
new GradientBackgroundGenerator(90, 30, new SingleColorGenerator(new Color(235, 255, 255)), new SingleColorGenerator(new Color(255, 195, 230))),
new NonLinearTextPaster(4, 4, new Color(11, 11, 11))
)
)}
),
180,
180000,
20000
);
}
private CaptchaService(){}
public static ImageCaptchaService getInstance(){
return SingletonHolder.imageCaptchaService;
}
}

Controller实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
@Controller
@RequestMapping("/code")
public class CaptchaController {
@ResponseBody
@RequestMapping(value = "/captchaImage")
public void getJCaptchaImage(HttpServletRequest request,HttpServletResponse response) throws Exception {
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/jpeg");
BufferedImage bi = CaptchaService.getInstance().getImageChallengeForID(request.getSession(true)
.getId());
ServletOutputStream out = response.getOutputStream();
ImageIO.write(bi, "jpg", out);
try {
out.flush();
} finally {
out.close();
}
return;
}
@ResponseBody
@RequestMapping(value = "/validate")
public Boolean login(String username, String password, String captcha, HttpServletRequest request) {
Boolean result = false;
Boolean isCaptchaCorrect = CaptchaService.getInstance().validateResponseForID(request.getSession().getId(), captcha);
if (isCaptchaCorrect) {
}
return result;
}
}

前端代码

1
<img id="verify" width="80" height="30" src="/code/captchaImage" />

测试结果

JCaptcha测试结果