- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章spring整合kaptcha验证码的实现由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
kaptcha简介
kaptcha是一个很有用的验证码生成工具,由于它有许多可配置项,所以用它可以简单快捷的生成各式各样的验证码.
开发工具及使用的核心技术
1、eclipse 。
2、mybatis 。
3、spring 。
4、springmvc 。
5、kaptcha 。
本文将介绍kaptcha两种使用方式
方式一:在 spring-kaptcha.xml 中配置 。
方式二:在 web.xml 中配置 。
正式开始
1、搭骨架 。
1、添加依赖
1
2
3
4
5
6
|
<!-- 验证码 -->
<dependency>
<groupid>com.github.penggle</groupid>
<artifactid>kaptcha</artifactid>
<version>
2.3
.
2
</version>
</dependency>
|
要使用kaptcha验证码,除了spring和mybatis那些依赖,只需引入这一个即可.
2、完善配置文件 。
①spring-dao.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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
<!-- 配置整合mybatis过程 -->
<!--
1
、配置数据库相关参数properties的属性:${url} -->
<context:property-placeholder location=
"classpath:jdbc.properties"
/>
<!--
2
、配置数据库连接池 -->
<bean id=
"datasource"
class
=
"com.mchange.v2.c3p0.combopooleddatasource"
>
<!-- 配置连接池属性 -->
<property name=
"driverclass"
value=
"${jdbc.driver}"
/>
<property name=
"jdbcurl"
value=
"${jdbc.url}"
/>
<property name=
"user"
value=
"${jdbc.username}"
/>
<property name=
"password"
value=
"${jdbc.password}"
/>
<!-- c3p0连接池的私有属性 -->
<property name=
"maxpoolsize"
value=
"30"
/>
<property name=
"minpoolsize"
value=
"10"
/>
<!-- 关闭连接不自动commit -->
<property name=
"autocommitonclose"
value=
"false"
/>
<!-- 获取连接超时时间 -->
<property name=
"checkouttimeout"
value=
"10000"
/>
<!-- 当获取连接失败时重试次数 -->
<property name=
"acquireretryattempts"
value=
"2"
/>
</bean>
<!--
3
、配置mybatis的sqlsessionfactory -->
<bean id=
"sqlsessionfactory"
class
=
"org.mybatis.spring.sqlsessionfactorybean"
>
<property name=
"datasource"
ref=
"datasource"
/>
<!-- 自动扫描mappers.xml文件 -->
<property name=
"mapperlocations"
value=
"classpath:mappers/*.xml"
/>
<!-- mybatis配置文件 -->
<property name=
"configlocation"
value=
"classpath:mybatis-config.xml"
/>
<!-- 扫描entity包,使用别名 -->
<property name=
"typealiasespackage"
value=
"com.zhu.kaptcha.entity"
></property>
</bean>
<!--
4
、dao接口所在包名,spring会自动查找其下的类 -->
<bean
class
=
"org.mybatis.spring.mapper.mapperscannerconfigurer"
>
<property name=
"basepackage"
value=
"com.zhu.kaptcha.dao"
/>
<property name=
"sqlsessionfactorybeanname"
value=
"sqlsessionfactory"
></property>
</bean>
|
②spring-service.xml 。
1
2
3
4
5
6
7
8
9
10
11
|
<!-- 扫描service包下所有使用注解的类型 -->
<context:component-scan base-
package
=
"com.zhu.kaptcha.service"
/>
<!-- 事务管理 -->
<bean id=
"transactionmanager"
class
=
"org.springframework.jdbc.datasource.datasourcetransactionmanager"
>
<property name=
"datasource"
ref=
"datasource"
/>
</bean>
<!-- 配置基于注解的声明式事物 -->
<tx:annotation-driven transaction-manager=
"transactionmanager"
/>
|
③spring-web.xml 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<!-- 配置springmvc -->
<!--
1
、开启springmvc注解模式 -->
<mvc:annotation-driven />
<!--
2
、定义视图解析器 -->
<bean id=
"viewresolver"
class
=
"org.springframework.web.servlet.view.internalresourceviewresolver"
>
<property name=
"prefix"
value=
"/"
/>
<property name=
"suffix"
value=
".jsp"
/>
</bean>
<!--
3
、扫描web相关的bean -->
<context:component-scan base-
package
=
"com.zhu.kaptcha.controller"
/>
|
④web.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
26
27
|
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-
class
>org.springframework.web.servlet.dispatcherservlet</servlet-
class
>
<init-param>
<param-name>contextconfiglocation</param-name>
<param-value>classpath:spring/spring-*.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 编码过滤器 -->
<filter>
<filter-name>encodingfilter</filter-name>
<filter-
class
>org.springframework.web.filter.characterencodingfilter</filter-
class
>
<async-supported>
true
</async-supported>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-
8
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
|
至此,骨架就搭起来了,接下来完成对数据库的操作.
2、对数据库的操作 。
1、entity层 。
user.java 。
1
2
3
4
5
|
public
class
user {
private
int
uid;
private
string username;
private
string password;
}
|
2、dao层 。
userdao.java 。
1
2
3
4
|
public
interface
userdao {
user finduserbyusername(string username);
}
|
userdao.xml 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<!doctype mapper
public
"-//mybatis.org//dtd mapper 3.0//en"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"
>
<mapper namespace=
"com.zhu.kaptcha.dao.userdao"
>
<select id=
"finduserbyusername"
resulttype=
"com.zhu.kaptcha.entity.user"
>
select *
from tb_user
where
user_name=#{username}
</select>
</mapper>
|
3、service层 。
userserviceimpl.java 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@service
public
class
userserviceimpl
implements
userservice {
@autowired
private
userdao userdao;
@override
public
boolean
login(string username, string password) {
user user = userdao.finduserbyusername(username);
if
(password.equals(user.getpassword())) {
return
true
;
}
else
{
return
false
;
}
}
}
|
注:写到dao层和service层应该做一下junit测试,测试比较简单,这里就不做说明了.
3、整合kaptcha 。
方式1、通过spring-kaptcha.xml配置 。
1、在resources的spring文件夹下新建 spring-kaptcha.xml 配置文件,内容如下
spring-kaptcha.xml 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<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"
>
125
</prop>
<prop key=
"kaptcha.image.height"
>
45
</prop>
<prop key=
"kaptcha.textproducer.font.size"
>
45
</prop>
<prop key=
"kaptcha.session.key"
>code</prop>
<prop key=
"kaptcha.textproducer.char.length"
>
4
</prop>
<prop key=
"kaptcha.textproducer.font.names"
>宋体,楷体,微软雅黑</prop>
</props>
</constructor-arg>
</bean>
</property>
</bean>
|
注:这个bean就是配置了一些验证码的属性,也可以直接写在spring-web.xml中,根据个人习惯,我喜欢把不同模块的配置写在不同的文件中.
2、新建一个controller用于生成验证码 。
codecontroller.java 。
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
|
@controller
public
class
codecontroller {
@autowired
private
producer captchaproducer =
null
;
@requestmapping
(
"/kaptcha"
)
public
void
getkaptchaimage(httpservletrequest request, httpservletresponse response)
throws
exception {
httpsession session = request.getsession();
response.setdateheader(
"expires"
,
0
);
response.setheader(
"cache-control"
,
"no-store, 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();
session.setattribute(constants.kaptcha_session_key, captext);
//向客户端写出
bufferedimage bi = captchaproducer.createimage(captext);
servletoutputstream out = response.getoutputstream();
imageio.write(bi,
"jpg"
, out);
try
{
out.flush();
}
finally
{
out.close();
}
}
}
|
注意:这个controller的路由为“kaptcha”,那么等下前端验证码的src就为kaptcha.jpg .
3、新建一个工具类用于比对验证码 。
codeutil.java 。
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
|
public
class
codeutil {
/**
* 将获取到的前端参数转为string类型
* @param request
* @param key
* @return
*/
public
static
string getstring(httpservletrequest request,string key) {
try
{
string result = request.getparameter(key);
if
(result !=
null
) {
result = result.trim();
}
if
(
""
.equals(result)) {
result =
null
;
}
return
result;
}
catch
(exception e) {
return
null
;
}
}
/**
* 验证码校验
* @param request
* @return
*/
public
static
boolean
checkverifycode(httpservletrequest request) {
//获取生成的验证码
string verifycodeexpected = (string) request.getsession().getattribute(com.google.code.kaptcha.constants.kaptcha_session_key);
//获取用户输入的验证码
string verifycodeactual = codeutil.getstring(request,
"verifycodeactual"
);
if
(verifycodeactual ==
null
||!verifycodeactual.equals(verifycodeexpected)) {
return
false
;
}
return
true
;
}
}
|
注意:这里get传的参数名为“verifycodeactual”,那么等下在页面中验证码的name值也得为这个.
接下来就可以使用验证码了! 。
4、用户登录的controller 。
usercontroller.java 。
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
|
@controller
@requestmapping
(
"/user"
)
public
class
usercontroller {
@autowired
private
userservice userservice;
@requestmapping
(
"/login"
)
public
string login(
@requestparam
(
"username"
) string username,
@requestparam
(
"password"
) string password,
httpservletrequest request) {
boolean
result = userservice.login(username, password);
if
(!codeutil.checkverifycode(request)) {
request.setattribute(
"codeerr"
,
"验证码有误!"
);
return
"fail"
;
}
else
{
if
(result) {
request.setattribute(
"user"
, username);
return
"success"
;
}
else
{
request.setattribute(
"errmsg"
,
"用户名或密码错误!"
);
return
"fail"
;
}
}
}
}
|
注:这里调用codeutil工具类比对输入的验证码是否正确.
5、前端页面 。
login.jsp 。
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
|
<%@ page language=
"java"
import
=
"java.util.*"
contenttype=
"text/html; charset=utf-8"
pageencoding=
"utf-8"
%>
<!doctype html
public
"-//w3c//dtd html 4.01 transitional//en"
"http://www.w3.org/tr/html4/loose.dtd"
>
<html>
<head>
<title>登录</title>
<script type=
"text/javascript"
>
function refresh() {
document.getelementbyid(
'captcha_img'
).src=
"kaptcha.jpg?"
+math.random();
}
</script>
</head>
<body>
<form action=
"${pagecontext.request.contextpath }/user/login"
method=
"post"
>
username:<input type=
"text"
name=
"username"
/><br />
password:<input type=
"password"
name=
"password"
/><br />
验证码: <input type=
"text"
placeholder=
"请输入验证码"
name=
"verifycodeactual"
>
<div
class
=
"item-input"
>
<img id=
"captcha_img"
alt=
"点击更换"
title=
"点击更换"
onclick=
"refresh()"
src=
"kaptcha.jpg"
/>
</div>
<input type=
"submit"
value=
"登录"
/>
</form>
</body>
</html>
|
success.jsp 。
1
2
3
|
<body>
<h1>欢迎登录,${user}</h1>
</body>
|
fail.jsp 。
1
2
3
4
5
|
<body>
对不起,登录失败,原因:<br>
${codeerr}
<h2>${errmsg}</h2>
</body>
|
注:login.jsp的js代码是完成“点击更换”功能;注意验证码的name要和传入工具类中的名字一样,src就是生成验证码的controller路由加上.jpg.
6、测试
输入正确的验证码
登录成功
输入错误的验证码
页面显示验证码有误
点击验证码可以更换! 。
方式2、在web.xml中配置验证码 。
相比于方式一,一增二减.
减
1、在上面那个项目的基础上,把 codecontroller.java删掉 .
2、把 spring-kaptcha.xml删掉 ,其他的保留.
增
1、在 web.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
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
|
<!-- 验证码 -->
<servlet>
<servlet-name>kaptcha</servlet-name>
<servlet-
class
>com.google.code.kaptcha.servlet.kaptchaservlet</servlet-
class
>
<!-- 是否有边框 -->
<init-param>
<param-name>kaptcha.border</param-name>
<param-value>no</param-value>
</init-param>
<!-- 字体颜色 -->
<init-param>
<param-name>kaptcha.textproducer.font.color</param-name>
<param-value>black</param-value>
</init-param>
<!-- 图片宽度 -->
<init-param>
<param-name>kaptcha.image.width</param-name>
<param-value>
135
</param-value>
</init-param>
<!-- 使用哪些字符生成验证码 -->
<init-param>
<param-name>kaptcha.textproducer.
char
.string</param-name>
<param-value>acdefhkprstwx345679</param-value>
</init-param>
<!-- 图片宽度 -->
<init-param>
<param-name>kaptcha.image.height</param-name>
<param-value>
50
</param-value>
</init-param>
<!-- 字体大小 -->
<init-param>
<param-name>kaptcha.textproducer.font.size</param-name>
<param-value>
43
</param-value>
</init-param>
<!-- 干扰线 -->
<init-param>
<param-name>kaptcha.noise.color</param-name>
<param-value>red</param-value>
</init-param>
<!-- 字符个数 -->
<init-param>
<param-name>kaptcha.textproducer.
char
.length</param-name>
<param-value>
4
</param-value>
</init-param>
<!-- 字体 -->
<init-param>
<param-name>kaptcha.textproducer.font.names</param-name>
<param-value>arial</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>kaptcha</servlet-name>
<url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
|
注:这段配置就是用来配置验证码的,注意最后的 <url-pattern>/kaptcha.jpg</url-pattern> 要与验证码中的 src = "kaptcha.jpg" 对应.
这样就完成了验证码的配置,接下来测试。 测试
输入错误的验证码
页面显示验证码错误
输入正确的验证码
登录成功
测试通过! 。
总结
1、在页面中加验证码很简单,只需要添加 <img src= "xx"> 即可。用一个img标签,然后通过src指向生成验证码的controller的路由加上 .jpg (验证码用spring方式配置),或者通过src指向 。
<url-pattern>/kaptcha.jpg</url-pattern> ,即 src="kaptcha.jpg" .
2、点击更换也简单,就是给img标签加一个onclick事件,然后用js完成.
点击更换的js
1
2
3
4
5
|
<script type=
"text/javascript"
>
function refresh() {
document.getelementbyid(
'captcha_img'
).src=
"kaptcha.jpg?"
+math.random();
}
</script>
|
然后在img标签中加上 onclick="refresh()" ,这样就完成了这个点击事件.
3、更多kaptcha属性的配置 。
。
constant | 描述 | 默认值 |
kaptcha.border | 图片边框,合法值:yes , no | yes |
kaptcha.border.color | 边框颜色,合法值: r,g,b (and optional alpha) 或者 white,black,blue. | black |
kaptcha.border.thickness | 边框厚度,合法值:>0 | 1 |
kaptcha.image.width | 图片宽 | 200 |
kaptcha.image.height | 图片高 | 50 |
kaptcha.producer.impl | 图片实现类 | com.google.code.kaptcha.impl.defaultkaptcha |
kaptcha.textproducer.impl | 文本实现类 | com.google.code.kaptcha.text.impl.defaulttextcreator |
kaptcha.textproducer.char.string | 文本集合,验证码值从此集合中获取 | abcde2345678gfynmnpwx |
kaptcha.textproducer.char.length | 验证码长度 | 5 |
kaptcha.textproducer.font.names | 字体 | arial, courier |
kaptcha.textproducer.font.size | 字体大小 | 40px. |
kaptcha.textproducer.font.color | 字体颜色,合法值: r,g,b 或者 white,black,blue. | black |
kaptcha.textproducer.char.space | 文字间隔 | 2 |
kaptcha.noise.impl | 干扰实现类 | com.google.code.kaptcha.impl.defaultnoise |
kaptcha.noise.color | 干扰 颜色,合法值: r,g,b 或者 white,black,blue. | black |
kaptcha.obscurificator.impl | 图片样式: 水纹com.google.code.kaptcha.impl.waterripple 鱼眼com.google.code.kaptcha.impl.fisheyegimpy 阴影com.google.code.kaptcha.impl.shadowgimpy |
com.google.code.kaptcha.impl.waterripple |
kaptcha.background.impl | 背景实现类 | com.google.code.kaptcha.impl.defaultbackground |
kaptcha.background.clear.from | 背景颜色渐变,开始颜色 | light grey |
kaptcha.background.clear.to | 背景颜色渐变, 结束颜色 | white |
kaptcha.word.impl | 文字渲染器 | com.google.code.kaptcha.text.impl.defaultwordrenderer |
kaptcha.session.key | session key | kaptcha_session_key |
kaptcha.session.date | session date | kaptcha_session_date |
。
以上内容属于个人笔记整理,如有错误,欢迎批评指正! 。
原文链接:https://www.jianshu.com/p/e5ffa123cda4 。
最后此篇关于spring整合kaptcha验证码的实现的文章就讲到这里了,如果你想了解更多关于spring整合kaptcha验证码的实现的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我尝试阅读有关 Spring BOM、Spring Boot 和 Spring IO 的文档。 但是没有说明,我们应该如何一起使用它们? 在我的项目中,我们已经有了自己的 Parent POM ,所以
我正在开发的很酷的企业应用程序正在转向 Spring。这对所有团队来说都是非常酷和令人兴奋的练习,但也是一个巨大的压力源。我们所做的是逐渐将遗留组件移至 Spring 上下文。现在我们有一个 huuu
我正在尝试使用 @Scheduled 运行 Spring 批处理作业注释如下: @Scheduled(cron = "* * * * * ?") public void launchMessageDi
我对这两个概念有点困惑。阅读 Spring 文档,我发现,例如。 bean 工厂是 Spring 容器。我还读到“ApplicationContext 是 BeanFactory 的完整超集”。但两者
我们有一个使用 Spring BlazeDS 集成的应用程序。到目前为止,我们一直在使用 Spring 和 Flex,它运行良好。我们现在还需要添加一些 Spring MVC Controller 。
假设我有一个类(class) Person带属性name和 age ,它可以像这样用 Spring 配置: 我想要一个自定义的 Spring 模式元素,这很容易做到,允许我在我的 Sp
如何在 Java 中以编程方式使用 Spring Data 创建 MongoDB 复合索引? 使用 MongoTemplate 我可以创建一个这样的索引:mongoTemplate.indexOps(
我想使用 spring-complex-task 执行我的应用程序,并且我已经构建了复杂的 spring-batch Flow Jobs,它执行得非常好。 你能解释一下spring批处理流作业与spr
我实现了 spring-boot 应用程序,现在我想将它用作非 spring 应用程序的库。 如何初始化 lib 类,以便 Autowiring 的依赖项按预期工作?显然,如果我使用“new”创建类实
我刚开始学习 spring cloud security,我有一个基本问题。它与 Spring Security 有何不同?我们是否需要在 spring boot 上构建我们的应用程序才能使用 spr
有很多人建议我使用 Spring Boot 而不是 Spring 来开发 REST Web 服务。我想知道这两者到底有什么区别? 最佳答案 总之 Spring Boot 减少了编写大量配置和样板代码的
您能向我解释一下如何使用 Spring 正确构建 Web 应用程序吗?我知道 Spring 框架的最新版本是 4.0.0.RELEASE,但是 Spring Security 的最新版本是 3.2.0
我如何才能知道作为 Spring Boot 应用程序的一部分加载的所有 bean 的名称?我想在 main 方法中有一些代码来打印服务器启动后加载的 bean 的详细信息。 最佳答案 如spring-
我有一个使用 Spring 3.1 构建的 RESTful API,也使用 Spring Security。我有一个 Web 应用程序,也是一个 Spring 3.1 MVC 应用程序。我计划让移动客
升级到 Spring 5 后,我在 Spring Rabbit 和 Spring AMQP 中遇到错误。 两者现在都设置为 1.5.6.RELEASE 有谁知道哪些版本应该与 Spring 5 兼容?
我现在已经使用 Spring Framework 3.0.5 和 Spring Security 3.0.5 多次了。我知道Spring框架使用DI和AOP。我还知道 Spring Security
我收到错误 Unable to Location NamespaceHandler when using context:annotation-config running (java -jar) 由
在 Spring 应用程序中嵌入唯一版本号的策略是什么? 我有一个使用 Spring Boot 和 Spring Web 的应用程序。 它已经足够成熟,我想对其进行版本控制并在运行时看到它显示在屏幕上
我正在使用 spring data jpa 进行持久化。如果存在多个具有相同名称的实体,是否有一种方法可以将一个实体标记为默认值。类似@Primary注解的东西用来解决多个bean的依赖问题 @Ent
我阅读了 Spring 框架的 DAOSupport 类。但是我无法理解这些 DAOSuport 类的优点。在 DAOSupport 类中,我们调用 getXXXTemplate() 方法来获取特定的
我是一名优秀的程序员,十分优秀!