原創(chuàng)聲明:本文為作者原創(chuàng),未經(jīng)允許不得轉(zhuǎn)載,經(jīng)授權(quán)轉(zhuǎn)載需注明作者和出處
上一章的demo中,我們不管是數(shù)據(jù)傳輸,業(yè)務(wù)處理還是持久化數(shù)據(jù)(操作數(shù)據(jù)庫(kù))都是在servlet文件中完成的,這樣做,可能會(huì)顯得比較亂,因此在實(shí)際開(kāi)發(fā)過(guò)程中,我們會(huì)根據(jù)不同的功能將項(xiàng)目分為幾個(gè)層級(jí):
今天用分層的方式帶大家做一個(gè)實(shí)戰(zhàn)小項(xiàng)目處理用網(wǎng)頁(yè)的登錄權(quán)限:實(shí)現(xiàn)用戶登錄之后進(jìn)入主頁(yè)并且顯示用戶姓名,并且一定時(shí)間內(nèi)直接輸入主頁(yè)的地址還是可以訪問(wèn),超過(guò)時(shí)間了再輸入主頁(yè)地址就需要重新登錄的功能:
項(xiàng)目結(jié)構(gòu)是這樣的:
<%@ 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="login" method="post">
<div style="color: red;">${requestScope.error }</div><!-- 獲取錯(cuò)誤信息 -->
用戶名:<input type="text" name="userName" /><br />
密碼:<input type="password" name="password" /><br />
<input type="submit" value="登錄" />
</form>
</body>
</html>
<%@ 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>主頁(yè)</title>
</head>
<body>
用戶編號(hào):${sessionScope.user.id }<br /><!-- 從session中獲取用戶參數(shù) -->
用戶名:${sessionScope.user.userName }
</body>
</html>
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接收到的賬號(hào)密碼
String userName = req.getParameter("userName");
String password = req.getParameter("password");
LoginService loginService = new LoginService();
boolean result = loginService.login(userName,password,req, resp);
if(result){
resp.sendRedirect(req.getContextPath()+"/index.jsp");//重定向到主頁(yè)
}else{
req.setAttribute("error", "用戶名或密碼輸入錯(cuò)誤");
req.getRequestDispatcher( "/login.jsp").forward(req,resp); //請(qǐng)求轉(zhuǎn)發(fā)到主頁(yè)
}
}
public boolean login(String userName, String password, HttpServletRequest req, HttpServletResponse resp) {
LoginDao loginDao = new LoginDao();
User user = loginDao.login(userName, password);
if(user!=null){//用戶不為空
// 手動(dòng)設(shè)置session的有效期為60秒
HttpSession session = req.getSession();
String sessionId = session.getId();
Cookie cookie = new Cookie("sessionId", sessionId);
cookie.setPath(req.getContextPath());
resp.addCookie(cookie);
session.setAttribute("user", user);
session.setMaxInactiveInterval(60);
return true;
}else{
return false;
}
}
LoginDao:主要實(shí)現(xiàn)持久化功能(和數(shù)據(jù)庫(kù)打交道)
public class LoginDao {
// JDBC 驅(qū)動(dòng)
private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
//數(shù)據(jù)庫(kù)地址 格式是 jdbc:mysql://數(shù)據(jù)庫(kù)地址(可以是ip地址):端口號(hào)(默認(rèn)是3306)/數(shù)據(jù)庫(kù)名
private static final String URL = "jdbc:mysql://localhost:3306/loginDemo";
// 數(shù)據(jù)庫(kù)的用戶名與密碼,需要根據(jù)自己的設(shè)置
private static final String USER = "root";
private static final String PASS = "root";
/**
* @Title: login
* @Description: TODO(登陸)
* @param @param userName
* @param @param password
* @param @return 設(shè)定文件
* @return User 返回類型
* @throws
*/
public User login(String userName, String password) {
Connection conn = null;
Statement stmt = null;
User user = null;
try{
// 注冊(cè) JDBC 驅(qū)動(dòng)器
Class.forName(JDBC_DRIVER);
// 打開(kāi)一個(gè)連接
conn = DriverManager.getConnection(URL,USER,PASS);
//拼接查詢的SQL語(yǔ)句
StringBuffer sql = new StringBuffer("SELECT * FROM USER WHERE userName = '");
sql.append(userName);
sql.append("' and password = '").append(password).append("'");
System.out.println(sql.toString());
// 執(zhí)行 SQL 語(yǔ)句
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql.toString());
// 展開(kāi)結(jié)果集數(shù)據(jù)
if(rs.next()){
//獲取查出來(lái)的字段
int id = rs.getInt("id");
userName = rs.getString("userName");
user = new User(id, userName);
}else{
user = null;
}
} catch(Exception se) {
// 處理 異常
se.printStackTrace();
}finally{
//關(guān)閉資源
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}
return user;
}
user: 實(shí)體類(參數(shù)封裝)
public class User {
private int id;//主鍵
private String userName;//用戶名
private String password;//密碼
/**
* 構(gòu)造函數(shù)
* <p>Title: </p>
* <p>Description: </p>
* @param id
* @param userName
*/
public User(int id, String userName) {
super();
this.id = id;
this.userName = userName;
}
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;
}
}
ok,以上就是本次實(shí)戰(zhàn)的主要代碼了,項(xiàng)目的邏輯:
那么當(dāng)我們?cè)L問(wèn)的時(shí)候,首先輸入錯(cuò)誤密碼:
輸入正確密碼:
登錄之后60(因?yàn)槌绦蚶镌O(shè)置的session過(guò)期時(shí)間為60秒)秒不操作或者沒(méi)有登錄的情況直接訪問(wèn)主頁(yè)地址:
登錄過(guò)后60秒之內(nèi)直接訪問(wèn)主頁(yè)地址:
最后附上項(xiàng)目源碼和Sql文件:
sql文件:https://pan.baidu.com/s/1bpIkgTx
項(xiàng)目源碼:http://pan.baidu.com/s/1bpF3xZD