在生活中,我們登陸一個網站的時候經常會碰到需要登陸的界面,而這種界面的通常會有一個輸入框,後面跟着一個圖片,叫你在輸入框中輸入圖片中的數字和字母,完成登錄校驗。
頁面如下圖所示:
而這種驗證碼是怎麼實現的呢?
下面就來寫一個小項目,來試一下這個登錄界面上加上一個驗證碼:(本項目使用spring+mybatis+servlet實現)
系統的基本流程就是:用戶通過前臺表單提交信息給servlet,servlet將前臺傳過來的信息和後臺傳過來的信息進行比較並跳轉頁面,而驗證碼的信息時存在session中的。
首先,我們建一個表:(實現登錄的校驗)
然後在eclipse中建立一個動態web工程(包結構如下)
在這裏插入圖片描述](https://img-blog.csdnimg.cn/20191027164436209.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3NzQ1NjM2,size_16,color_FFFFFF,t_70)
按照如圖所示建好包結構:
導包:
我們先建好實體類:Users.java (和數據庫中的字段對應好)
package com.zmx.pojo;
public class Users {
private Integer id;
private String username;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
第二步,編寫UsersMapper.java接口 (用來查詢用戶名和密碼是否和數據庫中匹配,這裏採用的是註解方式)
package com.zmx.mapper;
import org.apache.ibatis.annotations.Select;
import com.zmx.pojo.Users;
public interface UsersMapper {
@Select("select * from users where username=#{username} and password=#{password}")
Users selByUsersPwd(Users users);
}
第三步:編寫UsersService接口(用來執行業務邏輯)
package com.zmx.service;
import com.zmx.pojo.Users;
public interface UsersService {
Users login(Users users);
}
第四步:編寫UsersService接口的實現類UsersServiceImpl(業務邏輯實現類)
package com.zmx.service.impl;
import com.zmx.mapper.UsersMapper;
import com.zmx.pojo.Users;
import com.zmx.service.UsersService;
public class UsersServiceImpl implements UsersService {
private UsersMapper usersMapper;
public UsersMapper getUsersMapper() {
return usersMapper;
}
public void setUsersMapper(UsersMapper usersMapper) {
this.usersMapper = usersMapper;
}
public Users login(Users users) {
return usersMapper.selByUsersPwd(users);
}
}
這裏引入了UsersMapper,並實現了get/set方法,目的就是將UsersMapper注入UsersServiceImpl中,從而可以調用UsersMapper中的方法。
第五步:編寫Servlet(LoginServlet和ValidCodeServlet)
其中UsersServlet是用來進行數據校驗的,而ValidCodeServlet是用來創建一個驗證碼
首先,我們先來創建ValidCodeServlet:
package com.zmx.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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("/validcode")
public class ValidCodeServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//創建一張圖片
BufferedImage image = new BufferedImage(200, 100, BufferedImage.TYPE_INT_RGB);
//透明玻璃
Graphics2D gra = image.createGraphics();
//設置畫筆顏色
gra.setColor(Color.white);
//從哪個座標開始填充,後兩個參數,矩陣區域
gra.fillRect(0, 0, 200, 100);
//產生4個一位數的隨機數
List<Integer> randList = new ArrayList<Integer>();
Random rand = new Random();
for(int i=0; i < 4; i++) {
randList.add(rand.nextInt(10));
}
//設置畫筆的顏色及樣式
gra.setColor(Color.BLACK);
gra.setFont(new Font("宋體",Font.BOLD|Font.ITALIC,40));
Color[] colors = new Color[] {Color.RED,Color.YELLOW,Color.BLUE,Color.GREEN,Color.PINK,Color.GRAY};
//將rand產生的4個隨機數畫在透明玻璃上
for(int i=0; i < randList.size(); i++) {
gra.setColor(colors[rand.nextInt(colors.length)]);
gra.drawString(randList.get(i)+"", i*40, 70+(rand.nextInt(21)-10));
}
//在驗證碼圖片上隨機畫上2條線
for(int i = 0; i < 2; i++) {
gra.setColor(colors[rand.nextInt(colors.length)]);
//畫橫線
gra.drawLine(0, rand.nextInt(101), 200, rand.nextInt(101));
}
//設置圖片的格式,並輸出到頁面上
ServletOutputStream outputStream = resp.getOutputStream();
ImageIO.write(image, "jpg", outputStream);
//將驗證碼中的4位數字轉換成字符保存在session中
HttpSession session = req.getSession();
session.setAttribute("code", ""+randList.get(0)+randList.get(1)+randList.get(2)+randList.get(3));
}
}
LoginServlet:
package com.zmx.servlet;
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;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.zmx.pojo.Users;
import com.zmx.service.UsersService;
import com.zmx.service.impl.UsersServiceImpl;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private UsersService usersService;
@Override
public void init() throws ServletException {
ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
usersService = ac.getBean("usersService",UsersServiceImpl.class);
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String code = req.getParameter("code");
HttpSession session = req.getSession();
String codeSession = session.getAttribute("code").toString();
if(codeSession.equals(code)) {
String username = req.getParameter("username");
String password = req.getParameter("password");
Users users = new Users();
users.setUsername(username);
users.setPassword(password);
Users user = usersService.login(users);
if(user != null) {
resp.sendRedirect("main.jsp");
} else {
req.setAttribute("error", "用戶名或密碼不正確");
req.getRequestDispatcher("index.jsp").forward(req, resp);
}
} else {
req.setAttribute("error", "驗證碼不正確");
req.getRequestDispatcher("index.jsp").forward(req, resp);
}
}
}
spring的核心配置文件:applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="jdbc:mysql:///heima" />
<property name="username" value="root" />
<property name="password" value="123" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zmx.mapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean id="usersService" class="com.zmx.service.impl.UsersServiceImpl">
<property name="usersMapper" ref="usersMapper"></property>
</bean>
</beans>
log4j.properties
log4j.rootCategory=INFO, CONSOLE ,LOGFILE
log4j.logger.com.zmx.mapper=DEBUG
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%C %d{YYYY-MM-dd hh:mm:ss} %m %n
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=E:/my.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%m %n
在web.xml中配置:在tomcat啓動的時候就去加載spring核心配置文件
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
index.jsp中使用了js代碼,而點擊看不清的時候向ValidCodeServlet傳入一個時間戳的目的是,如果寫傳的話,因爲瀏覽器的緩存機制,頁面不會進行跳轉。
<%@ 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>
<script type="text/javascript" src="js/jquery-1.7.2.js"></script>
<script type="text/javascript">
$(function(){
$("a").click(function(){
$("img").attr("src","validcode?date="+new Date());
return false;
})
})
</script>
</head>
<body>
${error }
<form action="login" method="post">
<table>
<tr>
<td>用戶名:</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>密碼:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td>驗證碼:</td>
<td><input type="text" size="10" name="code" /><img src="validcode" width="80" height="40" /><a href="">看不清</a></td>
</tr>
<tr>
<td><input type="submit" value="登錄"></td>
<td><input type="reset" value="重置"></td>
</tr>
</table>
</form>
</body>
</html>
main.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>
成功跳轉
</body>
</html>
至此,這個小項目就算是完成了,
項目源碼附下:
https://pan.baidu.com/s/1A7uxTSIy_6C0Ppq9YXf19g