用eclipse写了一个学生管理系统sms项目,如下为目录结构:
我们先回忆下MVC和三层架构,先上图:
把MVC和三层架构分清楚之后就来开始我们的项目:
由于要实现的功能比较简单,项目也很小,需求也很简单,我们可以从数据库自顶向下写。
1.创建数据库表(MySQL中)。
登陆的话就需要一张用户信息表,用户是学生,学生登录会用到学号(num)和密码(password),表中必须要有的就有学号和密码;
数据库表必须要有一个主键,学号是与业务相关的,不能把它当作主键,可以设一个id,它是业务无关主键,把它设为Integer包装类,方便判断它是否为null。
还可以为学生添加姓名:name、年龄:age、分数:score等
2.根据MVC+三层架构的需要创建包
beans(模型)、servlets(控制器)、service(服务层)、DAO(数据持久层)、utils(工具类),
(包的名字自己取,分别以上面几个单词结尾就好)
3.根据数据库表在beans包下创建Student类
代码如下:
package com.zl.beans;
import java.io.Serializable;
public class Student implements Serializable {
private Integer id; //id是个业务无关主键,把它设为Integer包装类,可以判断它是否为null
private String num; //num是学号,但是不把它当主键
private String password; //登录密码
private String name;
private int age;
private double score;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String num,String password, String name, int age, double score) {
super();
this.num = num;
this.password = password;
this.name = name;
this.age = age;
this.score = score;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String toString() {
return "Student [id=" + id + ", num=" + num + ", password=" + password + ", name=" + name + ", age=" + age
+ ", score=" + score + "]";
}
}
4.写登录界面login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>学生登陆</title>
</head>
<body>
${message}<br>
<!--${pageContext.request.contextPath }获取当前应用的根 -->
<form action="${pageContext.request.contextPath}/loginServlet" method="post">
学号:<input type="text" name="num"><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
<a href="${pageContext.request.contextPath}/toRegisterServlet">注册</a>
</body>
</html>
5.写登录时负责跳转的Servlet,LoginServlet.java
需要先在web.xml里添加:
<servlet>
<display-name>LoginServlet</display-name>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.zl.servlets.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/loginServlet</url-pattern>
</servlet-mapping>
LoginServlet.java
package com.zl.servlets;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.zl.beans.Student;
import com.zl.service.IStudentService;
import com.zl.service.StudentServiceImpl;
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.接收请求
String num = request.getParameter("num");
String password = request.getParameter("password");
//获取session
HttpSession session = request.getSession();
/* "".equals(num.trim())表示用户输入了空串儿,但是是从表单登录的
* num == null为的是防止用户从地址栏访问 */
if(num == null || "".equals(num.trim())) {
//request.getRequestDispatcher("/login.jsp").forward(request,response);//请求转发时,若用户恶意刷新会占用服务端的资源
session.setAttribute("message", "学号输入有误!");
response.sendRedirect(request.getContextPath()+"/login.jsp");//重定向 , 防止恶意刷新
return;
}
if(password == null || "".equals(password.trim())) {
session.setAttribute("message", "密码输入有误!");
response.sendRedirect(request.getContextPath()+"/login.jsp");//重定向 , 防止恶意刷新
return;
}
//2.创建Service对象
IStudentService service = new StudentServiceImpl();//注意接口和实现类的命名方式
//3.调用Service对象的checkStudent()方法对用户进行验证
Student student = service.checkUser(num,password);
//4.验证通过,则跳转到系统主页index.jsp
response.sendRedirect(request.getContextPath()+"/index.jsp");//重定向 , 防止恶意刷新
//5.验证未通过,则跳转到登录页面,让用户再次登录,此时需要给用户一些提示信息
if(student == null) {
session.setAttribute("message", "用户名或密码输入有误!");
response.sendRedirect(request.getContextPath()+"/login.jsp");//重定向 , 防止恶意刷新
return;
}
}
}
6.根据在LoginServlet.java里的需要,创建相应的接口和实现类
接口:IStudentService.java
package com.zl.service;
import com.zl.beans.Student;
public interface IStudentService {
//对用户进行验证
Student checkUser(String num, String password);
//向DB中添加Student
Integer saveStudent(Student student);
}
实现类:StudentServiceImpl.java
package com.zl.service;
import com.zl.DAO.IStudentDao;
import com.zl.DAO.StudentDaoImpl;
import com.zl.beans.Student;
public class StudentServiceImpl implements IStudentService {
private IStudentDao dao;
public StudentServiceImpl() {
dao = new StudentDaoImpl();
}
public Student checkUser(String num, String password) {
return dao.selectStudentLogin(num,password);
}
@Override
public Integer saveStudent(Student student) {
return dao.insertStudent(student);
}
}
7.在utils包下写工具类JdbcUtils.java
package com.zl.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/*一旦工具类发生异常,若使用try catch捕捉异常,工具类的调用者根本不知道哪错了,所以工具类里一般不用try catch*/
public class JdbcUtils {
// 加载驱动
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 获取数据库连接Connection对象
private static Connection conn;
public static Connection getConnection() throws SQLException {
String url = "jdbc:mysql:///test"; // jdbc总协议,mysql子协议,///数据库在本机且端口号是3306,test数据库
String user = "root";
String password = "123456";
Connection conn = null;
if (conn == null || conn.isClosed()) {
conn = DriverManager.getConnection(url, user, password);
}
return conn;
}
// 关闭资源
public static void close(Connection conn, Statement stmt, ResultSet rs) throws SQLException {
if (conn != null && !conn.isClosed()) {
conn.close();
}
if (stmt != null && !stmt.isClosed()) {
stmt.close();
}
if (rs != null && !rs.isClosed()) {
rs.close();
}
}
}
8.写DAO层的接口和实现类
接口:IStudentDao.java
package com.zl.DAO;
import com.zl.beans.Student;
public interface IStudentDao {
Student selectStudentLogin(String num, String password);
return insertStudent(Student student);
}
实现类:StudentDaoImpl.java
package com.zl.DAO;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.zl.beans.Student;
import com.zl.utils.JdbcUtils;
public class StudentDaoImpl implements IStudentDao {
private Connection conn;
private Statement st;
private PreparedStatement ps;
private ResultSet rs;
@Override
public Student selectStudentLogin(String num, String password) {
Student student = null;
try {
conn = JdbcUtils.getConnection();
String sql = "select * from student where num=? and password=?";
ps = conn.prepareStatement(sql);
ps.setString(1, num);
ps.setString(2, password);
rs = ps.executeQuery();
if(rs.next()) {
student = new Student();
student.setId(rs.getInt("id"));
student.setNum(rs.getString("num"));
student.setName(rs.getString("name"));
student.setPassword(rs.getString("password"));
student.setAge(rs.getInt("age"));
student.setScore(rs.getDouble("score"));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
JdbcUtils.close(conn, ps, rs);
} catch (SQLException e) {
e.printStackTrace();
}
}
return student;
}
@Override
public Integer insertStudent(Student student) {
Integer id = null;
try {
conn = JdbcUtils.getConnection();
String sql = "insert into student(num,password,name,age,score) values(?,?,?,?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, student.getNum());
ps.setString(2, student.getPassword());
ps.setString(3, student.getName());
ps.setInt(4, student.getAge());
ps.setDouble(5, student.getScore());
ps.executeUpdate();
//sql = "select @@identity newId";//获取一个id(数据库表里的id是自增的)
sql = "select last_insert_id() newId";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
if(rs.next()){
id = rs.getInt("newId");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
JdbcUtils.close(conn, ps, rs);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return id;
}
}
登录写完了,下面写注册功能(在login.jsp中是通过超链接到注册界面的,MVC中,jsp不能直接到jsp,要通过一个Servlet)
9.帮助跳转的Servlet,ToRegisterServlet.java
package com.zl.servlets;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ToRegisterServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.sendRedirect(request.getContextPath()+"/register.jsp");
}
}
10.写一个注册界面register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>注册</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/registerServlet" method="post">
学号:<input type="text" name="num"><br>
密码:<input type="password" name="password"><br>
姓名:<input type="text" name="name"><br>
年龄:<input type="text" name="age"><br>
成绩:<input type="text" name="score"><br>
<input type="submit" value="注册">
</form>
</body>
</html>
11.Servlet帮助提交注册的数据,RegisterServlet.java
package com.zl.servlets;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.zl.beans.Student;
import com.zl.service.IStudentService;
import com.zl.service.StudentServiceImpl;
public class RegisterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
//1.获取表单参数
String num = request.getParameter("num");
String password = request.getParameter("password");
String name = request.getParameter("name");
String ageStr = request.getParameter("age");
String scoreStr = request.getParameter("score");
Integer age = Integer.valueOf(ageStr);
Double score = Double.valueOf(scoreStr);
//2.创建Student对象
Student student = new Student(num,password,name,age,score);
student.setPassword(password);
//3.创建Service对象
IStudentService service = new StudentServiceImpl();
//4.调用Service对象的saveStudent()方法将对象写入DB
Integer id = service.saveStudent(student);
//5.写入失败,则跳转到注册页面,重新注册
if(id == null) {
response.sendRedirect(request.getContextPath()+"/register.jsp");
return;
}
//6.写入成功,则跳转到登录页面
response.sendRedirect(request.getContextPath()+"/login.jsp");
}
}
这样用Servlet和jsp基于三层架构和MVC的简单登录和注册功能就写完了!!!