一 实验目的和要求
- 理解MVC设计模式。
- 掌握基于MVC(Servlet+JSP+JavaBean相结合)开发Java Web系统。
二 实验内容
基于MVC(Servlet+JSP+JavaBean相结合)实现用户的登录注册功能。
要求:用户信息至少包含:用户名和密码,用户名不能重复,注册时要求用户输入两次密码确认。
三 实验原理
MVC(JavaBean+JSP+Servlet相结合)适合开发复杂的Web应用,在这种模式下,Servlet负责处理用户请求并响应,JSP负责数据显示和与用户交互,JavaBean负责具体业务逻辑的处理。现在往往还引入DAO层(数据访问层),负责数据库的基本CRUD访问操作。
分层架构的代码基本是按照【域模型层(domain)】→【数据访问层(dao、dao.impl)】→【业务处理层(service、service.impl)】→【表现层(web.controller、web.UI、web.filter、web.listener)】→【工具类(util)】→【测试类(junit.test)】的顺序进行编写的。
四 实验步骤
1.创建数据库db_login,建表t_user
2.创建工程Dynamic Web Project,lxqMVC。
3.导入相关jar包,复制要导入的包,粘贴到lib文件夹下即可。
4. 建包(entity,dao,service,servlet,util)。
5. 创建实体类,dao实现类,业务类,Serlvet,工具类utils。
6.页面的编写(jsp)。
五 参考程序
- 创建视图层 jsp页面 (webContent目录下)
(1)登录界面 login.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录页面</title>
</head>
<style type="text/css">
#d1{
width: 500px;
margin: auto;
border: solid 1px;
border-radius: 10px;
}
h2{
text-align: center;
}
#d2{
width: 300px;
height:50px;
margin:0 auto;
}
</style>
<body>
<div id="d1">
<h2>用户登录</h2>
<form action="loginServlet" method="post">
用户名: <input type="text" name="username" placeholder="用户名">
<br><br>
密 码: <input type="password" name="password" placeholder="密码">
<br> <br>
<div id="d2">
<input type="submit" value="登录">
<a href="register.jsp">注册 </a>
</div>
</form>
</div>
</body>
</html>
(2)注册界面register.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>注册页面</title>
</head>
<style type="text/css">
#d1{
width: 500px;
margin: auto;
border: solid 1px;
border-radius: 10px;
}
h2{
text-align: center;
}
#d2{
width: 300px;
height:50px;
margin:0 auto;
}
</style>
<body>
<div id="d1">
<h2>用户注册</h2>
<form action="registerServlet" method="post">
用户名:
<input type="text" name="username" id="uname" value="" οnblur="CUname()" alt="用户名"/>
<span id="unameSpan"></span><br><br>
密码:
<input type="password" name="password" id="pwd" value="" οnblur="CPwd()"/>
<span id="pwdSpan"></span><br><br>
确认密码:
<input type="password" name=" pwd2"id="pwd2" value="" οnblur="CPwd2()"/>
<span id="pwd2Span"></span><br> <br>
<div id="d2">
<input type="reset" name="reset" id="reset" value="重置" οnblur="Clog()"/>
<input type="submit" name="log" id="log" value="注册" οnblur="Clog()"/>
</div>
</form>
</div>
</body>
<script type="text/javascript">
//用户名
function CUname(){
var uname=document.getElementById("username").value;
var span=document.getElementById("unameSpan");
if(uname=="" || uname==null){
span.innerHTML="用户名不能为空";
span.style.color="red";
}
}
//密码
function CPwd(){
var pwd=document.getElementById("password").value;
var span=document.getElementById("pwdSpan");
if(pwd=="" ||pwd==null){
span.innerHTML="*密码不能为空";
span.style.color="red";
return false;
}
CPwd2();
}
//确认密码
function CPwd2(){
var pwd=document.getElementById("password").value;
var pwd2=document.getElementById("pwd2").value;
var span=document.getElementById("pwd2Span");
if(pwd2==""||pwd2==null){
span.innerHTML="确认密码不能为空";
span.style.color="red";
return false;
}else{
span.innerHTML="两次密码不一致";
span.style.color="red";
return false;
}
}
</script>
</html>
(3)登录成功界面main.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>主界面</title>
</head>
<body>
<h1>登录成功!</h1>
</body>
</html>
(4)注册成功界面success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<h1>注册成功!</h1>
</body>
</html>
2.在包ycu.lxq.mvc.entity创建模型层 User.java 用户实体类
package ycu.lxq.mvc.entity;
public class User {
private int id;
private String username; //用户名
private String password; //密码
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int 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;
}
}
3.在包ycu.lxq.mvc.utils创建一个工具类JDBCUtil.java,用来与数据库打交道
package ycu.lxq.mvc.utils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
public class JDBCUtil {
private static DataSource dataSource;
static{
try {
//1.加载properties文件输入流
/*public ClassLoader getClassLoader()返回类的类加载器。
* ClassLoader类加载器,是负责加载类的对象,是一个抽象类。
* public static InputStream getSystemResourceAsStream(String name)打开输入流,
* 用于加载类的搜索路径中指定名称的资源。 该方法通过系统类加载器定位资源
* */
InputStream is = JDBCUtil.class.getResourceAsStream("/dbcpconfig.properties");
//InputStream is = JdbcUtils.class.getClassLoader().getSystemResourceAsStream("dbcpconfig.properties");
//2.加载输入流
/*public class Properties extends Hashtable<Object,Object>
* Properties类表示一组持久的属性。
* Properties可以保存到流中或从流中加载。
* 属性列表中的每个键及其对应的值都是一个字符串。
* */
Properties props = new Properties();
props.load(is); //从输入字节流读取属性列表(键和元素对)。
//3.创建数据源
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//获取数据源
public static DataSource getDataSource(){
return dataSource;
}
//获取连接
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();
}
//释放连接
public static void release(Connection conn, Statement st, ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if(st != null){
try {
st.close();
} catch (Exception e) {
e.printStackTrace();
}
st = null;
}
if(conn != null){
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
conn = null;
}
}
}
4.在src创建DBCP的配置文件dbcpconfig.properties。
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_login?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username=root
password=19980226
initialSize=10
maxActive=50
maxIdle=20
minIdle=5
maxWait=60000
connectionProperties=useUnicode=true;characterEncoding=utf8
defaultAutoCommit=true
defaultReadOnly=
defaultTransactionIsolation=READ_COMMITTED
5.在包ycu.lxq.mvc.dao创建数据库访问类 LoginDao.java类
package ycu.lxq.mvc.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import ycu.lxq.mvc.entity.User;
import ycu.lxq.mvc.utils.JDBCUtil;
public class LoginDao {
static Connection conn = null;
static PreparedStatement prst = null;
static ResultSet rs = null;
private User user = new User();
// 用户登录
public static int login(User user) throws Exception {
int result = -1;
conn = JDBCUtil.getConnection(); // 获取一个数据库连接
String sql = "select * from t_user where username=? and password=?"; // 编写sql语句
prst = conn.prepareStatement(sql); // 对ssql语句进行预处理
prst.setString(1, user.getUsername());
prst.setString(2, user.getPassword());
rs = prst.executeQuery(); // 执行sql语句, 并返回结果集
if (rs.next())
result = rs.getInt(1);
if (result > 0)
return 1;
else
return 0;
}
// 用户注册
public static boolean register(User user) throws Exception {
conn = JDBCUtil.getConnection(); // 获取数据库连接
String sql = "insert into t_user(username,password) values(?,?)"; // 编写sql语句
prst = conn.prepareStatement(sql); // 对sql语句进行预处理
prst.setString(1, user.getUsername());
prst.setString(2, user.getPassword());
boolean result = prst.executeUpdate() > 0; // 执行sql语句
return result;
}
}
6.在包ycu.lxq.mvc.servlet创建控制层servlet ,loginServlet.java和registerServlet.java
(1)loginServlet.java
package ycu.lxq.mvc.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 ycu.lxq.mvc.dao.LoginDao;
import ycu.lxq.mvc.entity.User;
@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public loginServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//response.getWriter().append("Served at: ").append(request.getContextPath());
//doPost(request, response);
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
User user=new User(username,password);
try {
int result=LoginDao.login(user);
if(result>0)
request.getRequestDispatcher("main.jsp").forward(request, response);
else
request.getRequestDispatcher("login.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
(2)registerServlet.java
package ycu.lxq.mvc.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 ycu.lxq.mvc.dao.LoginDao;
import ycu.lxq.mvc.entity.User;
@WebServlet("/registerServlet")
public class registerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public registerServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//response.getWriter().append("Served at: ").append(request.getContextPath());
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//doGet(request, response);
request.setCharacterEncoding("utf-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
User user=new User(username,password);
try {
boolean result=LoginDao.register(user);
if(result==true) {
System.out.println("注册成功!");
request.getRequestDispatcher("success.jsp").forward(request, response);
}else {
request.getRequestDispatcher("register.jsp").forward(request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
六 执行结果
1.登录界面
把数据库里添加的用户名和密码在这里输入就可以
2.登录成功界面
3.注册界面
输入一个新的用户名和密码
4.注册成功界面
注册成功,数据库中就会有刚刚注册的新用户。
七 实验总结
DBCP连接池实现数据库连接时,把DBCP的配置文件dbcpconfig.properties拷贝到类路径(src)下,但是没有修改密码,所以导致数据库一直连接不上,后来检查修改,最终连接上数据库。
在写register.jsp页面时,直接把之前做的页面复制过来了,但是运行的时候,能进去servlet,但是一直不能跳转到注册成功,然后就在registerServlet.java里分段检查,发现到了if里面就开始出错了,又开始检查LoginDao.java里的代码,也找不到错误,然后开始检查register.jsp代码,发现username和password的名字和数据库里的不一致,修改之后,显示正确。
注意: 本文使用DBCP连接池实现数据库连接,要把DBCP的配置文件dbcpconfig.properties里的用户名和密码修改为自己的。