1 验证码有啥用
在我们注册时,如果没有验证码的话,我们可以使用URLConnection来写一段代码发出注册请求。甚至可以使用while(true)来注册!那么服务器就废了!
验证码可以去识别发出请求的是人还是程序!当然,如果聪明的程序可以去分析验证码图片!但分析图片也不是一件容易的事,因为一般验证码图片都会带有干扰线,人都看不清,那么程序一定分析不出来。
2、实现过程图解(两个请求)
3、首先是登录界面login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<script type="text/javascript">
function _change()
{
var imgEle=document.getElementById("img");//得到img元素
//修改其src为/day12/VerifyCodeServlet+随机参数
imgEle.src="/day12/VerifyCodeServlet?a="+new Date().getTime();
}
</script>
<body>
<%
String message="";
String msg=(String)request.getAttribute("msg");
if(msg!=null)
{
message=msg;
}
%>
<h1>登录</h1><br/>
<font color="red"><b><%=message %></font>
<form action="/day12/LoginServlet" method="post">
用户名:<input type="text" name="username" /><br/>
密码:<input type="password" name="password" /><br/>
验证码:<input type="text" name="verifyCode" size="4"/>
<img src="/day12/VerifyCodeServlet" id="img">
<a href="javascript:_change()">换一张</a>
<br/>
<input type="submit" value="登录" />
</form>
</body>
</html>
4、验证码生成类
package ex01;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
public class VerifyCode {
private int w=70;
private int h=35;
private Random r=new Random();//生成随机数,后面可以调用
private String[] fontNames= {"宋体","华文楷体","微软雅黑","楷体","黑体"};
//可选字符
private String code= "23456789abcdefghijklmnopqrstuvwsyzABCDEFGHIJKLMNPQRSTUVWSYZ";
private Color bgColor=new Color(255,255,255);//背景色
private String text;//验证码上的文本
//生成随机颜色
private Color randomColor()
{
int red=r.nextInt(150);
int green=r.nextInt(150);
int blue=r.nextInt(150);
return new Color(red,green,blue);
}
private Font randomFont()
{
int index=r.nextInt(fontNames.length);
String fontName=fontNames[index];
int style=r.nextInt(4);//生成随机样式,0(无样式),1(粗体),2(斜体),3(粗体+斜体)
int size=r.nextInt(5)+24;//生成随机字号,24~28
return new Font(fontName,style,size);
}
//画干扰线
private void drawLine(BufferedImage image)
{
int num=3;//一共画三条
Graphics2D g2=(Graphics2D)image.getGraphics();//得到绘制环境
for(int i=0;i<num;i++)
{
int x1=r.nextInt(w);
int y1=r.nextInt(h);
int x2=r.nextInt(w);
int y2=r.nextInt(h);
g2.setStroke(new BasicStroke(1.5F));
g2.setColor(Color.blue);
g2.drawLine(x1, y1, x2, y2);//画线
}
}
//随机生成一个字符
private char randomChar()
{
int index=r.nextInt(code.length());
//charAt(int index)方法是一个能够用来检索特定索引下的字符的String实例的方法
return code.charAt(index);
}
//创建BufferImage图片缓冲区
private BufferedImage createImage()
{
BufferedImage image=new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
Graphics2D g2=(Graphics2D)image.getGraphics();
g2.setColor(this.bgColor);
g2.fillRect(0, 0, w, h);//填充矩形
return image;
}
//调用这个方法得到验证码
public BufferedImage getImage()
{
BufferedImage image=createImage();//创建图片缓冲区
Graphics2D g2=(Graphics2D)image.getGraphics();//得到绘制环境
StringBuilder sb=new StringBuilder();//得到用来装载生成验证码的文本
//向图片画4个字符
for(int i=0;i<4;i++)
{
String s=randomChar()+"";//随机生成一个字母
sb.append(s);//把字母添加到sb中去
float x=i*1.0F*w/4;//设置当前字符的x轴坐标
g2.setFont(randomFont());//随机设置字体
g2.setColor(randomColor());//随机设置颜色
g2.drawString(s,x,h-5);//画图
}
this.text=sb.toString();//把生成的字符赋值给this.text
drawLine(image);//添加干扰线
return image;//返回
}
//返回验证码图片的文本
public String getText()
{
return text;
}
//保存图片到指定的输出流
public static void output(BufferedImage image,OutputStream out) throws IOException
{
ImageIO.write(image,"JPEG",out);
}
}
5、在登录页面生成验证码VerifyCodeServlet
package ex01;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class VerifyCodeServlet
* 生成图片
* 保存图片上的文本到session
* 把图片响应给客户端
*/
@WebServlet("/VerifyCodeServlet")
public class VerifyCodeServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
VerifyCode vc=new VerifyCode();
BufferedImage image=vc.getImage();
request.getSession().setAttribute("session_code",vc.getText());
//把图片响应给客户端
VerifyCode.output(image, response.getOutputStream());
}
}
6、提交表单之后判断是否登录成功LoginServlet
package ex01;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/*校验验证码
* 1、从session获取正确验证码
* 2、从表单获取验证码
* 3、进行比较
* 4、如果相同,向下运行,负责保存错误信息到request域,转发到login.jsp
*/
String sessionCode=(String)request.getSession().getAttribute("session_code");
String paraCode=(String)request.getParameter("verifyCode");
if(!paraCode.equalsIgnoreCase(sessionCode))
{
request.setAttribute("msg", "验证码错误");
request.getRequestDispatcher("/session/login.jsp").forward(request, response);
return;
}
/*
* 获取表单数据
*/
//处理中文问题
request.setCharacterEncoding("utf-8");
//获取
String username=request.getParameter("username");
String passwork=request.getParameter("password");
//校验用户名和密码是否正确
if(!"kkk".equalsIgnoreCase(username))
{
//如果成功的话
HttpSession session=request.getSession();
session.setAttribute("username",username);
response.sendRedirect("/day12/session/succ1.jsp");
}
else
{
request.setAttribute("msg","您的用户名或密码输入错误");
request.getRequestDispatcher("/session/login.jsp").forward(request, response);
}
}
}
7、最后是登录成功后显示的页面succ1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>恭喜您!</h1>
</body>
</html>