81,094
社区成员
发帖
与我相关
我的任务
分享
public class RandomNumUtil {
private ByteArrayInputStream image;//图像
private String str;//验证码
private RandomNumUtil(){
init();//初始化属性
}
/*
* 取得RandomNumUtil实例
*/
public static RandomNumUtil Instance(){
return new RandomNumUtil();
}
/*
* 取得验证码图片
*/
public ByteArrayInputStream getImage(){
return this.image;
}
/*
* 取得图片的验证码
*/
public String getString(){
return this.str;
}
private void init() {
// 在内存中创建图象
int width=80, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 获取图形上下文
Graphics g = image.getGraphics();
// 生成随机类
Random random = new Random();
// 设定背景色
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);
// 设定字体
g.setFont(new Font("Times New Roman",Font.PLAIN,18));
// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}
// 取随机产生的认证码(4位数字)
String sRand="";
for (int i=0;i<4;i++){
String rand=String.valueOf(random.nextInt(10));
sRand+=rand;
// 将认证码显示到图象中
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));
// 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
g.drawString(rand,13*i+6,16);
}
//赋值验证码
this.str=sRand;
//图象生效
g.dispose();
ByteArrayInputStream input=null;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try{
ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);
ImageIO.write(image, "JPEG", imageOut);
imageOut.close();
input = new ByteArrayInputStream(output.toByteArray());
}catch(Exception e){
System.out.println("验证码图片产生出现错误:"+e.toString());
}
this.image=input;/* 赋值图像 */
}
/*
* 给定范围获得随机颜色
*/
private Color getRandColor(int fc,int bc){
Random random = new Random();
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
}
public class RandomAction extends ActionSupport{
private ByteArrayInputStream inputStream;
public String execute() throws Exception{
RandomNumUtil rdnu=RandomNumUtil.Instance();
this.setInputStream(rdnu.getImage());//取得带有随机字符串的图片
ActionContext.getContext().getSession().put("random", rdnu.getString());//取得随机字符串放入HttpSession
return SUCCESS;
}
public void setInputStream(ByteArrayInputStream inputStream) {
this.inputStream = inputStream;
}
public ByteArrayInputStream getInputStream() {
return inputStream;
}
}
* 登录执行的方法
*/
public String login(){
System.out.println("login执行了");
// 调用业务层的类
// 从session中取出RandomAction.java 中生成的验证码random
String arandom = (String) (ActionContext.getContext().getSession()
.get("random"));
String restr="success";
// 下面就是将session中保存验证码字符串与客户输入的验证码字符串对比了
if (arandom.equals(this.getRand())) {
User existUser=userService.login(user);
if(existUser==null){
//登录失败
//this.addActionError("用户名或密码错误");
ActionContext.getContext().put("msg", "用户名或密码错误");
restr="input";
}else{
//登录成功
ActionContext.getContext().getSession().put("username", existUser.getUsername());
ActionContext.getContext().put("msg", "登录成功");
ActionContext.getContext().getSession().put("userid", existUser.getUserid());
ActionContext.getContext().getSession()
.put("existUser",existUser);
restr="success";
}
}else{
this.addActionError("验证码错误");
restr="input";
}
return restr;
}
<form class="form-horizontal" id="userlogin" action="user_login" method="post" namespace="/">
<span class="heading">用户登录</span>
<input type="hidden" value="<s:property value='#request.msg'/>" id="msg"></input>
<%-- <s:hidden id="msg" value="%{#session.msg}"></s:hidden> --%>
<div class="form-group">
<input type="text" class="form-control" id="username" name="username" placeholder="用户名" onkeyup="(this.v=function(){this.value=this.value.replace(/[^A-Za-z0-9]+/,'');}).call(this)" onblur="this.v();">
<i class="fa fa-user"></i>
</div>
<div class="form-group help">
<input type="password" class="form-control" id="password" name="password" placeholder="密码">
<i class="fa fa-lock"></i>
</div>
<div class="form-group">
<s:text name="验证码"></s:text>:<s:textfield name="rand" size="5"></s:textfield><img src="rand.action" onclick="changeValidateCode(this)" title="点击图片刷新验证码"/><s:actionerror />
</div>
<s:hidden name="userid"></s:hidden>
<div class="form-group">
<a href="register.jsp">还没帐号?点我注册</a>
<input type="button" class="btn btn-default" onclick="checktosubmit()" value="登录"/>
</div>
</form>
<script type="text/javascript">
function checktosubmit(){
var username =document.getElementById("username").value;
var password =document.getElementById("password").value;
var msg=document.getElementById("msg").value;
if(username=="" || username==null){
alert("用户名不能为空");
return;
}else if(password=="" || password==null){
alert("密码不能为空");
return;
}else{
document.getElementById("userlogin").submit();
}
}
window.onload = function() {
var m=document.getElementById("msg").value;
if(m!=null&&m!=""){
alert(m);
}
};
function changeValidateCode(obj) {
//获取当前的时间作为参数,无具体意义
var timenow = new Date().getTime();
//每次请求需要一个不同的参数,否则可能会返回同样的验证码
//这和浏览器的缓存机制有关系,也可以把页面设置为不缓存,这样就不用这个参数了。
obj.src = "rand.action?d=" + timenow;
}
</script>
<%@ page contentType="image/jpeg" import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*" %>
<%!
Color getRandColor(int fc,int bc){//给定范围获得随机颜色
Random random = new Random();
if(fc>255) fc=255;
if(bc>255) bc=255;
int r=fc+random.nextInt(bc-fc);
int g=fc+random.nextInt(bc-fc);
int b=fc+random.nextInt(bc-fc);
return new Color(r,g,b);
}
%>
<%
//设置页面不缓存
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
// 在内存中创建图象
int width=60, height=20;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 获取图形上下文
Graphics g = image.getGraphics();
//生成随机类
Random random = new Random();
// 设定背景色
g.setColor(getRandColor(200,250));
g.fillRect(0, 0, width, height);
//设定字体
g.setFont(new Font("Times New Roman",Font.PLAIN,18));
//画边框
//g.setColor(new Color());
//g.drawRect(0,0,width-1,height-1);
// 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到
g.setColor(getRandColor(160,200));
for (int i=0;i<155;i++)
{
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x,y,x+xl,y+yl);
}
// 取随机产生的认证码(4位数字)
//String rand = request.getParameter("rand");
//rand = rand.substring(0,rand.indexOf("."));
String sRand="";
for (int i=0;i<4;i++){
String rand=String.valueOf(random.nextInt(10));
sRand+=rand;
// 将认证码显示到图象中
g.setColor(new Color(20+random.nextInt(110),20+random.nextInt(110),20+random.nextInt(110)));//调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
g.drawString(rand,13*i+6,16);
}
// 将认证码存入SESSION
session.setAttribute("rand",sRand);
// 图象生效
g.dispose();
// 输出图象到页面
ImageIO.write(image, "JPEG", response.getOutputStream());
out.clear();
out = pageContext.pushBody();
%>
在jsp页面使用<img src="xxx.jsp">引入。。。 function changeValidateCode(obj) {
//获取当前的时间作为参数,无具体意义
var timenow = new Date().getTime();
//每次请求需要一个不同的参数,否则可能会返回同样的验证码
obj.src = "rand.action?d=" + timenow;
}
比如只输错密码,验证码也会变,再输入正确的用户名和密码就能成功进去。这个时候的session里的 验证码为什么变了,不太理解
输错验证码,无论输入正确还是错误的密码都会提示验证码错误,得重启服务器才行
可以最先验证验证码
if(验证条件)
{
//验证码正确
if(user!=null)
{
ActionContext.getContext().getSession().put("existUser", existUser);
return "success";
}
else{
//登录失败
ActionContext.getContext().put("msg", "用户名或者密码错误");
return "input";
}
}
else{
//验证码有错误
ActionContext.getContext().put("msg", "验证码错误");
return "input";
}