做了一个简单的登录注册系统,基于MVC+三层架构的模式,关于MVC+三层架构模式的理解可以看这篇博客 https://blog.csdn.net/w_linux/article/details/79919523
下面是开发全过程
项目目录
一、创建数据库(MySQL)
create database sms;
use sms;
create table student(
id int(5) primary key auto_increment,
num varchar(5),
password varchar(32),
name varchar(32),
age int(3),
score double
);
#插入一条记录用来之后的测试
insert into student(id,num,password,name,age,score)
values(1,0001,123,'linjie',21,99);
二、JavaBean创建
因为在三层架构中View层、Service层、Dao层各司其职,而在MVC中三者model、view、controller三者合起来算是三层架构中的View层,JavaBean相当于model用来承载数据
package linjie.com.beans;
import java.io.Serializable;
public class Student implements Serializable {
private Integer id; //学生ID
private String num; //学号
private String name; //姓名
private String password; //密码
private int age; //年龄
private double score; //成绩
//无参构造器
public Student() {
super();
}
//带参构造器
public Student(String num, String name, int age, double score) {
super();
this.num = num;
this.name = name;
this.password = password;
this.age = age;
this.score = score;
}
//setters/getters
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 getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
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;
}
}
三、建立login.jsp
从三层架构里的View层开始上面JavaBean已经完成,现在就是MVC中的view了,当然我这里是用已经完成得项目来写,所以里面有些并没有出现的东西,不需要惊讶。
<%@ 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>SMS登录页面</title>
</head>
<body>
${message }<br>
<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>
四、建立LoginServlet.java(servlet)
model和view写完了,就要写控制器了,servlet就是控制器
控制器中的步骤如下
- 接收请求参数
- 创建Service对象
- 调用Service对象的chaeckUser()方法对用户进行验证
验证通过和未通过情况分析
package linjie.com.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 linjie.com.beans.Student; import linjie.com.service.IStudentService; import linjie.com.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(); if(num==null || "".equals(num.trim())) { 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对象的chaeckUser()方法对用户进行验证 Student student = service.checkUser(num,password); //4、验证未通过,则跳转到登录页面,让用户再次输入登录信息。此时页面需要给出用户一些提示 if(student==null) { session.setAttribute("message", "用户名或密码输入有误"); response.sendRedirect(request.getContextPath()+"/login.jsp"); return; } //4、验证通过,则跳转到系统主页index.jsp session.setAttribute("welcomeUser", num); response.sendRedirect(request.getContextPath()+"/index.jsp"); } }
注意一:
if(num == null || "".equals(num.trim()))
num==null防止用户直接通过地址栏访问,而不是通过表单输入
“”.equals(num.trim())防止用户输入空串
注意二:
为什么要在servlet中创建Service对象?
因为该项目是MVC+三层架构模型,所以servlet属于控制器,而系统业务逻辑需要在service中写(这里指验证用户请求参数),所以需要创建Service对象
五、消除servlet中的异常——>建立service接口以及其实现类
因为在servlet中已经创建了service对象,然而并没有创建这个接口以及其实现类。所以需要通过ctrl+1来消除servlet异常,并创建相应的接口或实现类
IStudentService接口
第二个saveStudent方法是之后用到的
package linjie.com.service;
import linjie.com.beans.Student;
public interface IStudentService {
//对用户进行验证
Student checkUser(String num, String password);
//向DB中添加Student
Integer savaStudent(Student student);
}
StudentServiceImpl实现类
package linjie.com.service;
import linjie.com.beans.Student;
import linjie.com.dao.IStudentDao;
import linjie.com.dao.StudentDaoImpl;
public class StudentServiceImpl implements IStudentService {
private IStudentDao dao;
public StudentServiceImpl() {
dao = new StudentDaoImpl();
}
@Override
public Student checkUser(String num, String password) {
return dao.selectStudentLogin(num,password);
}
@Override
public Integer savaStudent(Student student) {
return dao.insertStudent(student);
}
}
六、消除StudentServiceImpl中的异常——>创建Dao层(需要写jdbc工具类)
其实到这里就已经很清晰了,是一个很清楚的三层架构
IStudentDao接口
package linjie.com.dao;
import linjie.com.beans.Student;
public interface IStudentDao {
Student selectStudentLogin(String num, String password);
Integer insertStudent(Student student);
}
StudentDaoImpl实现类
到这里要注意,Dao层是要做什么的,是要与数据库来取得联系的,所以,这里应该先定义一个jdbc工具类,再写Dao层实现类
jdbcUtil.java
package linjie.com.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class jdbcUtil {
//加载DB驱动
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private static Connection conn;
//获取Connection对象
public static Connection getConnection() throws SQLException {
String url="jdbc:mysql://localhost:3306/sms";
String user="root";
String password="1111";
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();
}
}
}
StudentDaoImpl实现类
package linjie.com.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import linjie.com.beans.Student;
import linjie.com.utils.jdbcUtil;
public class StudentDaoImpl implements IStudentDao {
private Connection conn;
private Statement stmt;
private PreparedStatement ps;
private ResultSet rs;
@Override
public Student selectStudentLogin(String num, String password) {
Student student=null;
try {
conn = jdbcUtil.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) {
e.printStackTrace();
} finally {
try {
jdbcUtil.close(conn, ps, rs);
} catch (SQLException e) {
e.printStackTrace();
}
}
return student;
}
@Override
public Integer insertStudent(Student student) {
Integer id =null;
try {
conn = jdbcUtil.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";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
if(rs.next()) {
id = rs.getInt("newID");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
jdbcUtil.close(conn, ps, rs);
} catch (SQLException e) {
e.printStackTrace();
}
}
return id;
}
}
七、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>SMS注册页面</title>
</head>
<body>
${message }<br>
<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>
八、ToRegisterServlet
在登录页面跳转到注册页面的时候,因为涉及到跳转,如果是严格按照MVC的话,需要创建一个servlet,然后在servlet中重定向或请求转发到注册页面,也可以不严格的直接跳转注册页面
package linjie.com.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");
}
}
九、RegisterServlet
package linjie.com.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 linjie.com.beans.Student;
import linjie.com.service.IStudentService;
import linjie.com.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);
//创建student对象
Student student = new Student(num,name,age,score);
student.setPassword(password);
//创建service对象
IStudentService service = new StudentServiceImpl();
//调用service对象的saveStudent()方法,将数据写入DB
Integer id = service.savaStudent(student);
//写入失败
if(id == null) {
HttpSession session = request.getSession();
session.setAttribute("message", "没有注册成功");
response.sendRedirect(request.getContextPath()+"/register.jsp");
}
//写入成功
response.sendRedirect(request.getContextPath()+"/login.jsp");
}
}
十、
然后继续是service层、Dao层的使用,因为上述代码已经包含register的相关代码,这里不多做阐述了。
十一、总结
1、代码并不难,但是主要是理解了MVC+三层架构具体是如何应用的
2、在开发这个简单的项目过程中,其实出现了很多问题,比如不小心把sql文件给Build path了,结果半天没弄出来哪错了。还有就是版本的问题
源码我已经放到github了,可自行下载
https://github.com/ash-ali/SMS_LR