转自:https://blog.csdn.net/kkorkk/article/details/54292427
我们在登录或者注册的过程中,常常会发现有验证码的存在,今天我们自己动手来实现一个图片验证码。
首先,我们的验证码图片是在JSP页面中展示的,所以先从JSP页面着手。直接上代码。
login.jsp
[html] view plain copy
- <code class="language-html"> <body>
- <h2>欢迎登陆</h2><br>
- <form action="<%= request.getContextPath() %>/servlet/LoginServlet" method="get">
- <input type="text" name="validateCode">
- <img alt="点击更换验证码" src="<%= request.getContextPath() %>/servlet/Functio<span> </span>nServlet" id="img" onclick="reloadImg()">
- <input type="submit" value="提交" >
- </form>
- </body>
- <script type="text/javascript">
- function reloadImg(){
- var time = new Date().getTime();
- document.getElementById("img").src="<%= request.getContextPath()%>/servlet/FunctionServlet?d="+time;
- }
- </script>
- </code>
其中,LoignServlet是一个验证用户输入的验证码的Servlet,用户输入的表单信息将提交到这个Servlet。img的src由FunctionServlet提供,点击验证码将会更换一张新的验证码,实际上这是由JavaScript实现的,很简单。
再来看主角--FunctionServlet--具体生成验证码的Servlet。先上代码。
FunctionServlet.java
-
//定义随机字母库
-
static final char[] CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
-
//得到一个4位的随机字符数组
-
public static Random random = new Random();
-
static String getRandomString(){
-
StringBuffer randomString = new StringBuffer();
-
for(int i=0;i<4;i++){
-
randomString.append(CHARS[random.nextInt(CHARS.length)]);
-
}
-
return randomString.toString();
-
}
-
//获得随机颜色
-
static Color getRandomColor(){
-
return new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255));
-
}
-
public void doGet(HttpServletRequest request, HttpServletResponse response)
-
throws ServletException, IOException {
-
response.setContentType("image/jpeg"); //设置类型
-
String randomString = this.getRandomString(); //得到一个4位的验证码
-
request.getSession().setAttribute("randomString", randomString); //将验证字符串保存到会话中
-
int width=80,height=25; //设置验证码的宽高
-
Color c = this.getRandomColor(); //得到一种随机颜色
-
BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
-
Graphics2D g = bi.createGraphics();
-
g.fillRect(0, 0, width, height); //此行缺少,图片背景变为黑色
-
g.setColor(c);
-
g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,16));
-
g.drawString(randomString, 20, 20);
-
//设置图片噪点
-
for(int i=0;i<20;i++){
-
int x = random.nextInt(width);
-
int y = random.nextInt(height);
-
bi.setRGB(x, y,(int)(Math.random()*255));
-
}
-
//设置图片干扰线
-
for (int i = 0; i < 6; i++) {
-
//随机获取干扰线的起点和终点
-
int xstart = (int)(Math.random() * 80);
-
int ystart = (int)(Math.random() * 25);
-
int xend = (int)(Math.random() * 80);
-
int yend = (int)(Math.random() * 25);
-
g.setColor(new Color(random.nextInt(255),random.nextInt(255),random.nextInt(255)));
-
g.drawLine(xstart, ystart, xend, yend);
-
}
-
//输出验证码图片
-
ImageIO.write(bi, "JPG", response.getOutputStream());
-
}
具体思路并不复杂,先生成一个BufferImage对象,然后由BufferImage生成一个Graphics2D对象,接着往BufferImage对象中设置字符,之后再在Graphics2D对象中设置随机噪点和随机线条;最后输出整张图片。
再看LoginServlet,先上代码。
LoginServlet.java
-
public void doGet(HttpServletRequest request, HttpServletResponse response)
-
throws ServletException, IOException {
-
response.setContentType("text/html;charset=utf-8"); //少了此行文字乱码
-
String imageCode = (String) request.getSession().getAttribute("randomString");
-
String validateCode = (String) request.getParameter("validateCode");
-
//验证用户输入的验证码--不分大小写
-
if(imageCode.equalsIgnoreCase(validateCode)){
-
response.getWriter().print("登陆成功!");
-
}else{
-
response.getWriter().print("登陆失败!");
-
}
-
}
这个比较简单,思路就是从login.jsp中获取用户输入的验证码,与session中保存的字符相比较,再输出比较结果。
最后,别忘了配置web.xml,如果是使用MyEclipse,软件会自动帮你配置好。
上结果图。