这一篇是用来记录我编写学生信息管理系统时实现登录操作的过程,这是学生信息管理系统的第一个模块,之后我还会陆续将其它模块分享出来。
通过对管理员在前台页面输入的用户名,密码和验证码进行校验,校验通过即可登录成功转到查询页面,校验失败则在页面上显示相应的错误。
1.前台页面的登录逻辑使用Java编写。
2.页面的展示使用jsp。
3.由于这是一个为学生信息管理系统所做的登录页面,学生信息将会存储在数据库中,所以我们将管理员的信息也存入数据库之中。
我们把项目分为如图所示的几个层次:
1.web层:用来存放jsp页面和用来接收页面数据并进行逻辑处理 的servlet。
2.service层:组合Dao层中的简单方法,形成复杂的功能。
3.dao层:定义了对于数据库最基本的CRUD操作。
4.util:存放一些自己定义的工具类。
5.domain:用来存放实体类
CREATE DATABASE chapter07; -- 创建数据库
USE chapter07; -- 使用数据库
CREATE TABLE USER( -- 创建表
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20) NOT NULL,
gender VARCHAR(5),
age INT,
address VARCHAR(32),
class VARCHAR(50),
tel VARCHAR(20),
username VARCHAR(20),
PASSWORD VARCHAR(20)
);
ALTER TABLE USER CHANGE class cls VARCHAR(50)
SELECT * FROM USER
INSERT INTO USER(`id`,`name`,`gender`,`age`,`address`,`class`,`tel`,`username`,`password`) VALUES(1,'管理员',NULL,NULL,NULL,NULL,NULL,'administrators','123');
注意:在创建变量的时候需要与数据库中的变量名保持一致。
package com.itevent.domain;
public class Users {
private int id;
private String name;
private String gender;
private int age;
private String address;
private String cls;
private String tel;
private String username;
private String password;
public Users() {
}
public Users(int id, String name, String gender, int age, String address, String cls, String tel, String username, String password) {
this.id = id;
this.name = name;
this.gender = gender;
this.age = age;
this.address = address;
this.cls = cls;
this.tel = tel;
this.username = username;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCls() {
return cls;
}
public void setCls(String cls) {
this.cls = cls;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
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;
}
@Override
public String toString() {
return "Users{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", address='" + address + '\'' +
", cls='" + cls + '\'' +
", tel='" + tel + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
在这里我使用的是Druid,如果各位用的是其他的数据库连接池可以自行更改。
package com.itevent.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* JDBC工具类 使用Durid连接池
*/
public class JDBCUtils {
private static DataSource ds ;
static {
try {
//1.加载配置文件
Properties pro = new Properties();
//使用ClassLoader加载配置文件,获取字节输入流
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//2.初始化连接池对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接池对象
*/
public static DataSource getDataSource(){
return ds;
}
/**
* 获取连接Connection对象
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
1.对验证码进行校验,首先我们需要获取到用户输入的用户名,密码和验证码等数据,将用户输入的验证码与后台生成的验证码进行比对,如果验证码错误,则在页面的提示框中显示错误的信息,如果验证码正确则继续进行用户名和密码的验证,有了验证码可以避免机器登录恶意访问,提高了安全性能,也减少了对数据库的操作。
2.将获取到的用户名和密码封装为一个users对象,现在,我们拥有数据之后需要对数据库进行操作,所以在dao层中我们创建一个通过用户名和密码查询的方法,参数为username和password,在其中定义sql语句进行查询的操作,返回的对象用service来接受,在登录的servlet里边封装调用此方法。
package com.itevent.web.servlet;
import javax.imageio.ImageIO;
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 java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
* 验证码
*/
@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
//服务器通知浏览器不要缓存
response.setHeader("pragma", "no-cache");
response.setHeader("cache-control", "no-cache");
response.setHeader("expires", "0");
//在内存中创建一个长80,宽30的图片,默认黑色背景
//参数一:长
//参数二:宽
//参数三:颜色
int width = 80;
int height = 30;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//获取画笔
Graphics g = image.getGraphics();
//设置画笔颜色为灰色
g.setColor(Color.gray);
//填充图片
g.fillRect(0, 0, width, height);
//产生4个随机验证码,
String checkCode = getcheckCode();
//将验证码放入HttpSession中
request.getSession().setAttribute("checkCode",checkCode);
//设置画笔颜色为黄色
g.setColor(Color.yellow);
//设置字体的小大
g.setFont(new Font("黑体",Font.BOLD,24));
//向图片上写入验证码
g.drawString(checkCode,15,25);
//将内存中的图片输出到浏览器
//参数一:图片对象
//参数二:图片的格式,如PNG,JPG,GIF
//参数三:图片输出到哪里去
ImageIO.write(image,"PNG",response.getOutputStream());
}
/**
* 产生4位随机字符串
*/
private String getcheckCode(){
String base = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
Random r = new Random();
int size = base.length();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 4; i++) {
//产生0到size-1的随机值
int index = r.nextInt(size);
//在base字符串中获取下标为index的字符
char ch = base.charAt(index);
//将c放入到StringBuffer中去
sb.append(ch);
}
return sb.toString();
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request,response);
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>管理员登录</title>
<!-- 1. 导入CSS的全局样式 -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 2. jQuery导入,建议使用1.9以上的版本 -->
<script src="js/jquery-2.1.0.min.js"></script>
<!-- 3. 导入bootstrap的js文件 -->
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript">
function refreshCode() {
//绑定单击事件
var vocode = document.getElementById("vcode");
vcode.src = "${pageContext.request.contextPath}/checkCodeServlet?time="+new Date().getTime();
}
</script>
</head>
<body>
<div class="container" style="width: 400px;">
<h3 style="text-align: center;">管理员登录</h3>
<form action="${pageContext.request.contextPath}/loginServlet" method="post">
<div class="form-group">
<label for="username">用户名:</label>
<input type="text" name="username" class="form-control" id="username" placeholder="请输入用户名"/>
</div>
<div class="form-group">
<label for="password">密码:</label>
<input type="password" name="password" class="form-control" id="password" placeholder="请输入密码"/>
</div>
<div class="form-inline">
<label for="vcode">验证码:</label>
<input type="text" name="verifycode" class="form-control" id="verifycode" placeholder="请输入验证码" style="width: 120px;"/>
<a href="javascript:refreshCode()">
<img src="${pageContext.request.contextPath}/checkCodeServlet" title="看不清点击刷新" id="vcode"/>
</a>
</div>
<hr/>
<div class="form-group" style="text-align: center;">
<input class="btn btn btn-primary" type="submit" value="登录">
</div>
</form>
<!-- 出错显示的信息框 -->
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" >
<span>×</span></button>
<strong>${login_msg}</strong>
</div>
</div>
</body>
</html>
package com.itevent.web.servlet;
import com.itevent.domain.Users;
import com.itevent.service.UserService;
import com.itevent.service.impl.UserServiceImpl;
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 java.io.IOException;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置编码
request.setCharacterEncoding("utf-8");
//2.获取数据
String username = request.getParameter("username");
String password = request.getParameter("password");
String verifycode = request.getParameter("verifycode");
//3.判断验证码是否正确
HttpSession session = request.getSession();
String checkCode = (String)session.getAttribute("checkCode");//获取用户输入的验证码
session.removeAttribute("checkCode");//保证了验证码的唯一性
//对验证码进行校验
if (verifycode == null || ! checkCode.equalsIgnoreCase(verifycode)){
request.setAttribute("login_msg","验证码错误!");
//跳转登录页面
request.getRequestDispatcher("/login.jsp").forward(request,response);
return;
}
//4.封装user对象
Users users = new Users();
users.setUsername(username);
users.setPassword(password);
//5.调用service中的登录方法
UserService service = new UserServiceImpl();
Users adm = service.login(users);
//6.判断输入的数据是否正确
if (adm != null){
//验证成功
//跳转页面
response.sendRedirect(request.getContextPath()+"/index.jsp");
}else {
//验证失败
request.setAttribute("login_msg","用户名或密码错误!");
//发送信息
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
package com.itevent.service;
import com.itevent.domain.Users;
public interface UserService {
/**
* 通过用户名和密码查找管理员
* @return
* @param users
*/
Users login(Users users);
}
package com.itevent.service.impl;
import com.itevent.dao.UserDao;
import com.itevent.dao.impl.UserDaoImpl;
import com.itevent.domain.Users;
import com.itevent.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao dao = new UserDaoImpl();
@Override
public Users login(Users users) {
//返回查询的结果
return dao.findAdm(users.getUsername(),users.getPassword());
}
}
package com.itevent.dao;
import com.itevent.domain.Users;
public interface UserDao {
Users findAdm(String username, String password);
}
package com.itevent.dao.impl;
import com.itevent.dao.UserDao;
import com.itevent.domain.Users;
import com.itevent.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
public class UserDaoImpl implements UserDao {
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
@Override
public Users findAdm(String username,String password) {
try {
//要和数据库中的名字保持一致
String sql = "select * from user where username = ? and password = ?";
Users adm = template.queryForObject(sql, new BeanPropertyRowMapper<Users>(Users.class), username, password);
return adm;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
这是初始化页面
这是验证码输入有误的情况
用户名或密码输入错误
登陆成功后会跳转的下一个页面(这个页面只是一个测试页面)
1.在刚开始向数据库中存储管理员数据的时候只是将他的用户名和密码给保存了,其它的数据取了默认值,到最后我要检查我的用户名输入是否正确的时候,程序一直显示我的用户名或密码错误,起初我并不知道是什么原因,只是在代码上看过来看过去,我觉的我编写的逻辑并没有什么问题,所以在程序中打了几个点,debug了一下,发现问题出在UserDaoImpl中,执行完sql语句之后并没能封装成一个users对象,出现了数据转换异常,因为age的数据没有填写导致问题。如果你使用我上边创建的管理员数据也会出现同样的问题。
2.在写登录页面的逻辑操作的时候,出现了很多小bug,因为找不到令人很头疼,而且对与web项目中的debug还不太熟悉,只能凭着感觉来打点,找bug所在,慢慢摸索怎么打点。debug也是我所需要学习的地方
这是我的第一次将自己所做的项目用博客的形式写了出来,因为想记录一下自己写代码时的过程,把自己写代码的思路和步骤还有自己所碰到的问题展示出来,相当于做一个笔记吧。
之前跟着视频敲代码,感觉挺良好,啥都会,等到自己一上手,全都懵。所以看会了不代表你会了。代码只有多敲一敲才能发现自己的问题,从而解决问题,最后掌握问题。
这是学生信息管理系统的第一个模块,之后我还会陆续将其它模块给各位分享出来,如果你发现我的代码有什么错误或者可以改进的地方评论出来,大家共同进步!