Struts2教程系列(四) 验证码

时间:2022-12-30 18:56:44

转载请注明出处:http://blog.csdn.net/github_39430101/article/details/75268999

上一节我们讲了struts2如何前后呼应,这一节我们来实现登陆页面或者注册页面经常用到的验证码。
Struts2教程系列(四) 验证码
页面比较简陋,大家可以自行修改。下面我们来看是如何实现的。(自己依照前三章的内容写一个登录页面,我这里是一个表单)

步骤一:创建生成图片工具类

package com.util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
/**
* 生成验证码图片工具类
*/

public final class ImageUtil {
private static final char[] chars = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' };
private static final int SIZE = 4;
private static final int LINES = 5;
private static final int WIDTH = 80;
private static final int HEIGHT = 40;
private static final int FONT_SIZE = 30;
/**
* 生成验证码图片,封装与Map中。
* 其中Map的key是验证码,Map的value是验证码图片。
*/

public static Map<String, BufferedImage> createImage() {
StringBuffer sb = new StringBuffer();
BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
BufferedImage.TYPE_INT_RGB);
Graphics graphic = image.getGraphics();
graphic.setColor(Color.LIGHT_GRAY);
graphic.fillRect(0, 0, WIDTH, HEIGHT);
Random ran = new Random();
// 画随机字符
for (int i = 1; i <= SIZE; i++) {
int r = ran.nextInt(chars.length);
graphic.setColor(getRandomColor());
graphic.setFont(new Font(null, Font.BOLD + Font.ITALIC, FONT_SIZE));
graphic.drawString(chars[r] + "", (i - 1) * WIDTH / SIZE,
HEIGHT / 2);
sb.append(chars[r]);// 将字符保存,存入Session
}
// 画干扰线
for (int i = 1; i <= LINES; i++) {
graphic.setColor(getRandomColor());
graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT),
ran.nextInt(WIDTH), ran.nextInt(HEIGHT));
}
Map<String, BufferedImage> map = new HashMap<String, BufferedImage>();
map.put(sb.toString(), image);
return map;
}
/**
* 将图片转换为输入流
*/

public static InputStream getInputStream(BufferedImage image)
throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
encoder.encode(image);
byte[] imageBts = bos.toByteArray();
InputStream in = new ByteArrayInputStream(imageBts);
return in;
}
private static Color getRandomColor() {
Random ran = new Random();
Color color = new Color(ran.nextInt(256), ran.nextInt(256),
ran.nextInt(256));
return color;
}
}

步骤二:在控制器中Action中生成图片
创建CreateImageAction类

package day01;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import com.util.ImageUtil;

public class CreateImageAction extends BaseAction {
/**
* 验证码图片输入流
*/

private InputStream imageStream;
public String execute() {
// 创建验证码图片
Map<String, BufferedImage> imageMap = ImageUtil.createImage();
// 取出验证码,放入session
String code = imageMap.keySet().iterator().next();
session.put("imageCode", code);
// 取出图片
BufferedImage image = imageMap.get(code);
try {
// 将图片转变为输入流
imageStream = ImageUtil.getInputStream(image);
} catch (IOException e) {
e.printStackTrace();
return "error";
}
return "success";
}
public InputStream getImageStream() {
return imageStream;
}
public void setImageStream(InputStream imageStream) {
this.imageStream = imageStream;
}
}

步骤三:在struts.xml中配置action

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">


<!--
打开登录页面:
1、action的class属性可以省略,省略时Struts2
会自动实例化默认的Action类ActionSupport,
该类中有默认业务方法execute,返回success。
2、action的method属性可以省略,省略时Struts2
会自动调用execute方法。
-->

<struts>
<package name="day01" namespace="/login" extends="struts-default">
<action name="toLogin">
<result name="success">/WEB-INF/login.jsp</result>
</action>
</package>
<package name="login" namespace="/login" extends="struts-default">
<!--生成验证码 -->
<action name="createImage" class="day01.CreateImageAction">
<!--使用stream类型的result -->
<result name="success" type="stream">
<!--指定输出的内容 -->
<param name="inputName">imageStream</param>
</result>
</action>
</package>
</struts>

步骤四:修改登录页面
在登录页面login.jsp上,将img的src属性指定为生成验证码图片的action,即 createImage。并且为了每次点击该图片时都刷新为新验证码,给该img的单击事件绑定函数,在函数中刷新img的src属性

<%@ page language="java" 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>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>欢迎登录</title>
<script type="text/javascript" language="javascript">
//刷新验证码图片
function change(image){
//改变img的src即可,由于该URL并没有变化,因此追加动态参数伪装成变化的URL。
image.src = "createImage?date=" + new Date().getTime();
}
</script>
</head>
<body>
<form action="#" method="submit">

用户名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/><br/>
<td class="login_info">验证码:</td>
<td class="width70"><input name="" type="text" class="width70" /></td>
<td><img src="createImage" alt="验证码" title="点击更换" onclick="change(this);"/></td><br/>
<input type="submit" value="登录"/>
</form>
</body>
</html>

最后,部署项目并测试:打开浏览器输入 http://localhost:8080/struts/login/toLogin
Struts2教程系列(四) 验证码