一啃沪、系統(tǒng)功能結(jié)構(gòu)圖
-
項(xiàng)目結(jié)構(gòu)圖
-
數(shù)據(jù)庫結(jié)構(gòu)圖
二码荔、項(xiàng)目搭建前期準(zhǔn)備
2.1 Maven 創(chuàng)建 web 項(xiàng)目
- Maven 相關(guān)鏈接
- 測試環(huán)境:
JDK17
扫俺、Tomcat-10.0.16
辐烂、mysql-8.0.28
2.2 配置 pom.xml 并導(dǎo)入相關(guān)依賴
-
JSTL
需要把相應(yīng) jar 包復(fù)制到 Tomcat 服務(wù)器:查看相關(guān)鏈接
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>smbms</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<!--Servlet 依賴-->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
</dependency>
<!--JSP 依賴-->
<dependency>
<groupId>com.guicedee.services</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>62</version>
</dependency>
<!--jstl 表達(dá)式依賴-->
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>2.0.0</version>
</dependency>
<!--標(biāo)簽庫依賴-->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-spec</artifactId>
<version>1.2.5</version>
</dependency>
<!--MySQL 依賴-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!--單元測試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<!--fastjson 依賴-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
</dependencies>
</project>
2.3 IDEA 中配置 Tomcat
配置
web.xml
<!--修改為與Tomcat 10 一致-->
<!--去掉 metadata-complete="true",開啟注解-->
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<!--設(shè)置首頁-->
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<!--設(shè)置Session默認(rèn)過期時間30分鐘-->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
2.4 創(chuàng)建項(xiàng)目包
-
結(jié)構(gòu)圖:
2.5 創(chuàng)建并連接數(shù)據(jù)庫
- 導(dǎo)入數(shù)據(jù)庫 相關(guān)鏈接
- IDEA 連接數(shù)據(jù)庫 相看相關(guān)鏈接
2.6 編寫實(shí)體類
-
在
pojo
包下編寫對應(yīng)數(shù)據(jù)表的實(shí)體類:Bill
邻寿、Provider
污茵、Role
、User
; -
IDEA 快捷方式創(chuàng)建實(shí)例類:
-
連接數(shù)據(jù)庫后闪萄,在數(shù)據(jù)表上右鍵點(diǎn)擊梧却;
-
選擇創(chuàng)建位置;
-
修改包路徑败去;
根據(jù)需求修改文件名稱放航;
-
Bill.java
:
public class Bill {
private Integer id; // 主鍵ID
private String billCode; // 賬單編碼
private String productName; // 商品名稱
private String productDesc; // 商品描述
private String productUnit; // 商品單位
private BigDecimal productCount; // 商品數(shù)量
private BigDecimal totalPrice; // 商品總額
private Integer isPayment; // 是否支付(1:未支付 2:已支付)
private Integer createdBy; // 創(chuàng)建者(userId)
private Date creationDate; // 創(chuàng)建時間
private Integer modifyBy; // 更新者(userId)
private Date modifyDate; // 更新時間
private Integer providerId; // 供應(yīng)商ID
private String providerName; // 供應(yīng)商名稱(聯(lián)表查詢字段)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBillCode() {
return billCode;
}
public void setBillCode(String billCode) {
this.billCode = billCode;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductDesc() {
return productDesc;
}
public void setProductDesc(String productDesc) {
this.productDesc = productDesc;
}
public String getProductUnit() {
return productUnit;
}
public void setProductUnit(String productUnit) {
this.productUnit = productUnit;
}
public BigDecimal getProductCount() {
return productCount;
}
public void setProductCount(BigDecimal productCount) {
this.productCount = productCount;
}
public BigDecimal getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(BigDecimal totalPrice) {
this.totalPrice = totalPrice;
}
public Integer getIsPayment() {
return isPayment;
}
public void setIsPayment(Integer isPayment) {
this.isPayment = isPayment;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Integer getModifyBy() {
return modifyBy;
}
public void setModifyBy(Integer modifyBy) {
this.modifyBy = modifyBy;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
public Integer getProviderId() {
return providerId;
}
public void setProviderId(Integer providerId) {
this.providerId = providerId;
}
public String getProviderName() {
return providerName;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
}
-
Provider.java
:
public class Provider {
private Integer id; // 主鍵ID
private String proCode; // 供應(yīng)商編碼
private String proName; // 供應(yīng)商名稱
private String proDesc; // 供應(yīng)商詳細(xì)描述
private String proContact; // 供應(yīng)商聯(lián)系人
private String proPhone; // 聯(lián)系電話
private String proAddress; // 地址
private String proFax; // 傳真
private Integer createdBy; // 創(chuàng)建者(userId)
private Date creationDate; // 創(chuàng)建時間
private Date modifyDate; // 更新時間
private Integer modifyBy; // 更新者(userId)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProCode() {
return proCode;
}
public void setProCode(String proCode) {
this.proCode = proCode;
}
public String getProName() {
return proName;
}
public void setProName(String proName) {
this.proName = proName;
}
public String getProDesc() {
return proDesc;
}
public void setProDesc(String proDesc) {
this.proDesc = proDesc;
}
public String getProContact() {
return proContact;
}
public void setProContact(String proContact) {
this.proContact = proContact;
}
public String getProPhone() {
return proPhone;
}
public void setProPhone(String proPhone) {
this.proPhone = proPhone;
}
public String getProAddress() {
return proAddress;
}
public void setProAddress(String proAddress) {
this.proAddress = proAddress;
}
public String getProFax() {
return proFax;
}
public void setProFax(String proFax) {
this.proFax = proFax;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
public Integer getModifyBy() {
return modifyBy;
}
public void setModifyBy(Integer modifyBy) {
this.modifyBy = modifyBy;
}
}
-
Role.java
:
public class Role {
private Integer id; // 主鍵ID
private String roleCode; // 角色編碼
private String roleName; // 角色名稱
private Integer createdBy; // 創(chuàng)建者
private Date creationDate; // 創(chuàng)建時間
private Integer modifyBy; // 修改者
private Date modifyDate; // 修改時間
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getRoleCode() {
return roleCode;
}
public void setRoleCode(String roleCode) {
this.roleCode = roleCode;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Integer getModifyBy() {
return modifyBy;
}
public void setModifyBy(Integer modifyBy) {
this.modifyBy = modifyBy;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
-
User.java
:
public class User {
private Integer id; // 主鍵ID
private String userCode; // 用戶編碼
private String userName; // 用戶名稱
private String userPassword; // 用戶密碼
private Integer gender; // 性別(1:女、 2:男)
private Date birthday; // 出生日期
private String phone; // 手機(jī)
private String address; // 地址
private Integer userRole; // 用戶角色(取自角色表-角色id)
private Integer createdBy; // 創(chuàng)建者(userId)
private Date creationDate; // 創(chuàng)建時間
private Integer modifyBy; // 更新者(userId)
private Date modifyDate; // 更新時間
private Integer age;// 年齡
private String userRoleName; // 用戶角色名稱(聯(lián)表查詢字段)
public Integer getAge() {
Date date = new Date();
Integer age = date.getYear() - birthday.getYear();
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getUserRoleName() {
return userRoleName;
}
public void setUserRoleName(String userRoleName) {
this.userRoleName = userRoleName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserCode() {
return userCode;
}
public void setUserCode(String userCode) {
this.userCode = userCode;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getUserRole() {
return userRole;
}
public void setUserRole(Integer userRole) {
this.userRole = userRole;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Integer getModifyBy() {
return modifyBy;
}
public void setModifyBy(Integer modifyBy) {
this.modifyBy = modifyBy;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
2.7 編寫基礎(chǔ)公共類
-
resources
包下圆裕,新建db.properties
文件:
# MySQL8
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=123456
- 編寫數(shù)據(jù)庫的公共類:
dao
包下創(chuàng)建BaseDao.java
public class BaseDao {
private static String driver;
private static String url;
private static String username;
private static String password;
/**
* 靜態(tài)代碼塊广鳍,類加載的同時進(jìn)行初始化
* 從配置文件中獲取數(shù)據(jù)庫配置
*/
static {
// 創(chuàng)建屬性集合
Properties params = new Properties();
String configFile = "db.properties";
// 通過類加載器讀取對應(yīng)資源,讀取數(shù)據(jù)庫連接信息,得到輸入流
InputStream is = BaseDao.class.getClassLoader().getResourceAsStream(configFile);
// 讀取流
try {
params.load(is);
} catch (IOException e) {
e.printStackTrace();
}
// 獲取數(shù)據(jù)庫配置屬性
driver = params.getProperty("driver");
url = params.getProperty("url");
username = params.getProperty("username");
password = params.getProperty("password");
}
/**
* 獲取數(shù)據(jù)庫連接
*
* @return 數(shù)據(jù)庫對象
*/
public static Connection getConnection() {
Connection connection = null;
try {
// 加載驅(qū)動
Class.forName(driver);
// 獲取數(shù)據(jù)庫連接對象
connection = DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return connection;
}
/**
* 編寫查詢公共方法
*
* @param connection 數(shù)據(jù)連接對象
* @param preparedStatement SQL的執(zhí)行對象
* @param resultSet 查詢結(jié)果集
* @param sql sql語句
* @param params 占位符
* @return 查詢結(jié)果集
* @throws SQLException
*/
public static ResultSet execute(Connection connection, PreparedStatement preparedStatement,
ResultSet resultSet, String sql, Object[] params) throws SQLException {
// 獲取sql語句的執(zhí)行對象 PreparedStatement(對SQL進(jìn)行預(yù)編譯)
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
// 為占位符參數(shù)賦值葫辐,占位符:索引從1開始搜锰,數(shù)組:索引從0開始
preparedStatement.setObject(i + 1, params[i]);
}
// 獲取查詢結(jié)果集
resultSet = preparedStatement.executeQuery();
return resultSet;
}
/**
* 編寫增、刪耿战、改公共方法
*
* @param connection 數(shù)據(jù)連接對象
* @param sql sql語句
* @param params 占位符
* @param preparedStatement SQL的執(zhí)行對象
* @return updateRows 記錄條數(shù)
* @throws SQLException
*/
public static int execute(Connection connection, PreparedStatement preparedStatement,
String sql, Object[] params) throws SQLException {
// 獲取sql語句的執(zhí)行對象 PreparedStatement(對SQL進(jìn)行預(yù)編譯)
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
// 為占位符參數(shù)賦值蛋叼,索引從1開始
preparedStatement.setObject(i + 1, params[i]);
}
// 獲取增、刪剂陡、改狈涮,記錄條數(shù)
int updateRows = preparedStatement.executeUpdate();
return updateRows;
}
/**
* 釋放資源,順序:后開先關(guān)
*
* @param resultSet 結(jié)果集
* @param preparedStatement 執(zhí)行sql的對象
* @param connection 數(shù)據(jù)庫對象
* @return flag 是否關(guān)閉成功
*/
public static boolean closeResource(Connection connection,
PreparedStatement preparedStatement,
ResultSet resultSet) {
boolean flag = true;
// 關(guān)閉結(jié)果集
if (resultSet != null) {
try {
resultSet.close();
// GC回收
resultSet = null;
} catch (SQLException e) {
e.printStackTrace();
// 設(shè)置異常時為false
flag = false;
}
}
// 關(guān)閉 preparedStatement
if (preparedStatement != null) {
try {
preparedStatement.close();
preparedStatement = null;
} catch (SQLException e) {
e.printStackTrace();
flag = false;
}
System.out.println(flag);
}
// 關(guān)閉 connection
if (connection != null) {
try {
connection.close();
connection = null;
} catch (SQLException e) {
e.printStackTrace();
flag = false;
}
}
return flag;
}
}
2.8 編寫字符編碼過濾器
-
filter
包下鸭栖,創(chuàng)建過濾器文件:
/**
* 編碼過濾器:注意:過濾器繼續(xù)執(zhí)行的代碼8桠伞!
* 用注解的方式晕鹊,過濾所有內(nèi)容:也可以通過配置web.xml
*/
@WebFilter("/*")
public class CharacterEncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=utf-8");
// 注意:過濾器繼續(xù)執(zhí)行K扇础!
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
- 在
web.xml
中注冊溅话,也通過注解方式@WebFilter("/*")
晓锻;
2.9 導(dǎo)入靜態(tài)資源
-
放在
webapp
目錄下:
三、登錄功能的實(shí)現(xiàn)
3.1 流程結(jié)構(gòu)
3.2 導(dǎo)入前端頁面
- 導(dǎo)入登錄頁面
login.jsp
及其它jsp
頁面飞几; - 將登錄頁面
login.jsp
設(shè)置為首頁:在web.xml
中配置砚哆;
<!--設(shè)置首頁頁面-->
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
3.3 編寫后端文件
- 編寫 dao 層:
- 功能:操作數(shù)據(jù)庫
- 通過
userCode
查詢,業(yè)務(wù)層傳遞的登錄用戶
是否存在屑墨;
- 通過
-
dao
中新建user
包躁锁,創(chuàng)建UserDao
接口類:
public interface UserDao {
/**
* 得到要登錄的用戶
*
* @param connection 數(shù)據(jù)庫連接對象
* @param userCode 用戶名
* @return 登錄用戶
*/
public User getLoginUser(Connection connection, String userCode) throws SQLException;
}
- 編寫
UserDao
接口的實(shí)現(xiàn)類UserDaoImpl
:
public class UserDaoImpl implements UserDao {
/**
* 得到要登錄的用戶
*
* @param connection 數(shù)據(jù)庫連接對象
* @param userCode 用戶名
* @return User
* @throws SQLException
*/
@Override
public User getLoginUser(Connection connection, String userCode) throws SQLException {
PreparedStatement pstm = null;
ResultSet rs = null;
User user = null;
// 判斷數(shù)據(jù)庫是否連接成功,
if (connection != null) {
// 創(chuàng)建SQL
String sql = "select * from `smbms_user` where `userCode`=?";
Object[] params = {userCode};
// 執(zhí)行SQL
rs = BaseDao.execute(connection, pstm, rs, sql, params);
while (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setUserCode(rs.getString("userCode"));
user.setUserName(rs.getString("userName"));
user.setUserPassword(rs.getString("userPassword"));
user.setGender(rs.getInt("gender"));
user.setBirthday(rs.getDate("birthday"));
user.setPhone(rs.getString("phone"));
user.setAddress(rs.getString("address"));
user.setUserRole(rs.getInt("userRole"));
user.setCreatedBy(rs.getInt("createdBy"));
user.setCreationDate(rs.getTimestamp("creationDate"));
user.setModifyBy(rs.getInt("modifyBy"));
user.setModifyDate(rs.getTimestamp("modifyDate"));
}
BaseDao.closeResource(null, pstm, rs);
}
return user;
}
}
- 編寫業(yè)務(wù)層
- 功能:調(diào)用 dao 層
- 通過前端傳遞的用戶編碼
userCode
卵史,調(diào)用dao
層战转,查詢用戶是否存在;
- 通過前端傳遞的用戶編碼
- 在
service
下新建user
包以躯,創(chuàng)建UserService
接口:
public interface UserService {
// 用戶登錄
public User login(String userCode, String password);
}
- 編寫業(yè)務(wù)層接口的實(shí)現(xiàn)類
- 業(yè)務(wù)層調(diào)用 dao 層匣吊,必須先引入 dao 層;
- 引入方式:在構(gòu)造函數(shù)中將其實(shí)例化;
public class UserServiceImpl implements UserService {
// 業(yè)務(wù)層都會調(diào)用dao層色鸳,所以需要引入dao層
private UserDao userDao;
// 通過構(gòu)造函數(shù)社痛,類實(shí)例化時,創(chuàng)建UserDao的實(shí)例
public UserServiceImpl() {
userDao = new UserDaoImpl();
}
/**
* 用戶登錄
*
* @param userCode
* @param password
* @return
*/
@Override
public User login(String userCode, String password) {
Connection connection = null;
User user = null;
try {
connection = BaseDao.getConnection();
// 業(yè)務(wù)層調(diào)用dao層:對應(yīng)具體的數(shù)據(jù)庫操作
user = userDao.getLoginUser(connection, userCode);
} catch (SQLException e) {
e.printStackTrace();
} finally {
BaseDao.closeResource(connection, null, null);
}
return user;
}
}
- 編寫 Servlet(控制層)
- 功能:調(diào)用業(yè)務(wù)層
- 獲取前端輸入的用戶名命雀、密碼和數(shù)據(jù)庫查詢的內(nèi)容做比對蒜哀;
- 在
util
包下,創(chuàng)建Constants
類吏砂,存儲常量:
public class Constants {
public final static String USER_SESSION = "userSession";
}
- 在
servlet
包中新建user
包撵儿,創(chuàng)建LoginServlet
類:
// 通過注解方式,注冊servlet狐血,也可通過web.xml配置
@WebServlet("/login.do")
public class LoginServlet extends HttpServlet {
// Servlet:控制層淀歇,調(diào)用業(yè)務(wù)層
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("login.do=========LoginServlet start...");
// 從前端獲取輸入的用戶名、密碼
String userCode = req.getParameter("userCode");
String userPassword = req.getParameter("userPassword");
// 調(diào)用業(yè)務(wù)層:和數(shù)據(jù)庫中密碼進(jìn)行對比
UserService userService = new UserServiceImpl();
// 得到登錄人信息
User user = userService.login(userCode, userPassword);
// 如果用戶存在,且密碼正確匈织,可以登錄
if (user != null && userPassword.equals(user.getUserPassword())) { // 將用戶信息存儲到Session
req.getSession().setAttribute(Constants.USER_SESSION, user);
// 跳轉(zhuǎn)到主頁
resp.sendRedirect(req.getContextPath() + "/jsp/frame.jsp");
} else {
// 用戶不存在浪默,無法登錄
// 轉(zhuǎn)發(fā)回登錄頁面,順帶提示:用戶名或密碼錯誤
req.setAttribute("error", "用戶名或者密碼不正確");
req.getRequestDispatcher("login.jsp").forward(req, resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 注冊 servlet:可以配置
web.xml
或注解方式:@WebServlet("/login.do")
缀匕;
<!--注冊登錄頁面的Servlet-->
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>類名</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login.do</url-pattern>
</servlet-mapping>
- 測試訪問纳决,查看以上功能是否可以正常運(yùn)行;
四乡小、登錄功能的優(yōu)化
4.1 注銷功能
- 移除 session阔加,返回登錄頁面:
servlet.user
下創(chuàng)建LogoutServlet
類:
// 注解方式,注冊servlet
@WebServlet("/jsp/logout.do")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 移除用戶的Session
req.getSession().removeAttribute(Constants.USER_SESSION);
// 返回登頁面
resp.sendRedirect(req.getContextPath() + "/login.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 注冊 servlet:
web.xml
或注解方式满钟;
4.2 登錄攔截器
- 功能:未登錄狀態(tài)下胜榔,不能訪問
jsp
目錄下的所有頁面; - 在
filter
下創(chuàng)建SysFilter
類:-
注意:執(zhí)行完過濾內(nèi)容湃番,必須添加讓過濾器繼續(xù)往下執(zhí)行的代碼:
chain.doFilter(req, resp);
-
注意:執(zhí)行完過濾內(nèi)容湃番,必須添加讓過濾器繼續(xù)往下執(zhí)行的代碼:
// 注冊過濾器
@WebFilter("/jsp/*")
public class SysFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
// 類型轉(zhuǎn)換:獲取session夭织、重定向
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
// 從session中獲取用戶
User user = (User) request.getSession().getAttribute(Constants.USER_SESSION);
// 如果session為空(注銷或未登錄),跳轉(zhuǎn)到錯誤頁面
if (user == null) {
response.sendRedirect(request.getContextPath() + "/error.jsp");
}
// 過濾器繼續(xù)執(zhí)行G@薄!
chain.doFilter(req, resp);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
- 注冊過濾器:
web.xml
中或注解方式:@WebFilter("/jsp/*")
<filter>
<filter-name>Sysfilter</filter-name>
<filter-class>類名</filter-class>
</filter>
<filter-mapping>
<filter-name>Sysfilter</filter-name>
<url-pattern>/jsp/*</url-pattern>
</filter-mapping>
4.3 密碼修改
思路:自頂向下設(shè)計(jì)奴饮,自底向上實(shí)現(xiàn)纬向;
-
先寫基本邏輯戴卜,前端在測試后端時逾条,逐漸完善:
需要自底向上糕篇,逐一實(shí)現(xiàn)功能墩崩,修改密碼需要更新數(shù)據(jù)庫,需要到
dao
層侯勉,進(jìn)行增鹦筹、刪、改址貌、查铐拐;dao
層需要的信息,比如:用戶名芳誓、當(dāng)前的密碼余舶、要修改的密碼,需要從Service
層獲惹绿省匿值;Service
層,需要負(fù)責(zé)把從Servlet
層傳過來的數(shù)據(jù)赂摆,進(jìn)行相應(yīng)的處理挟憔、驗(yàn)證、核算烟号,然后將最終的信息绊谭,傳遞給dao
層磨取;而
Servlet
直接與前端接觸程拭,返回當(dāng)前頁面上傳遞過來的,用戶輸入觸發(fā)的 參數(shù)劳吠,轉(zhuǎn)發(fā)到不同的頁面迫筑,交給不同的Service
來處理這些請求宪赶;
意味著,先從
dao
層開始寫分模塊脯燃,先寫接口搂妻,再寫接口的實(shí)現(xiàn)類,依次寫Service
和servlet
辕棚,最后注冊Servlet
欲主,然后測試并完善前端頁面邓厕;
- 編寫 dao 層
- 在
dao.user.UserDao
的接口下增加,用戶修改密碼接口:
/**
* 修改當(dāng)前用戶密碼
*
* @param connection 數(shù)據(jù)庫連接對象
* @param id 用戶Id
* @param password 新密碼
* @return 更新記錄數(shù)
* @throws SQLException
*/
public int updatePwd(Connection connection, int id, String password) throws SQLException;
- 編寫接口實(shí)現(xiàn)類:
UserDaoImpl
中增加:
/**
* 修改當(dāng)前用戶密碼
*
* @param connection 數(shù)據(jù)庫連接對象
* @param id 用戶Id
* @param password 新密碼
* @return updateRows
* @throws SQLException
*/
@Override
public int updatePwd(Connection connection, int id, String password) throws SQLException {
PreparedStatement pstm = null;
int updateRows = 0;
if (connection != null) {
String sql = "update `smbms_user` set `userPassword`=? where id=?";
Object[] params = {password, id};
updateRows = BaseDao.execute(connection, pstm, sql, params);
BaseDao.closeResource(null, pstm, null);
}
return updateRows;
}
- 編寫業(yè)務(wù)層 Service
- 添加接口:在
UserService
接口類下增加:
// 根據(jù)用戶Id扁瓢,修改密碼
public boolean updatePwd(int id, String pwd);
- 接口實(shí)現(xiàn)類:在
UserServiceImpl
下增加:
/**
* 根據(jù)用戶Id详恼,修改密碼
*
* @param id 用戶Id
* @param pwd 新密碼
* @return boolean
*/
@Override
public boolean updatePwd(int id, String pwd) {
boolean flag = false;
Connection connection = null;
try {
connection = BaseDao.getConnection();
if (userDao.updatePwd(connection, id, pwd) > 0) {
flag = true;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
BaseDao.closeResource(connection, null, null);
}
return flag;
}
- 編寫 Servlet
- 在
servlet.user
包下,創(chuàng)建UserServlet
類:- 通過前端傳遞的
method
值涤妒,做判斷单雾,去執(zhí)行操作,實(shí)現(xiàn)servlet
復(fù)用她紫;
- 通過前端傳遞的
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 實(shí)現(xiàn)servlet復(fù)用硅堆,實(shí)現(xiàn)復(fù)用需要提取出方法,然后在doGet函數(shù)中調(diào)用即可
String method = req.getParameter("method");
// 修改密碼
if (method.equals("savepwd") && method != null) {
this.updatePwd(req, resp);
}
}
// 在doGet外添加復(fù)用方法
/**
* 修改密碼
*
* @param req
* @param resp
*/
private void updatePwd(HttpServletRequest req, HttpServletResponse resp) {
// 獲取session
Object o = req.getSession().getAttribute(Constants.USER_SESSION);
String newpassword = req.getParameter("newpassword");
// 設(shè)置標(biāo)志位
boolean flag = false;
if (o != null && newpassword != null && newpassword.length() != 0) {
// 調(diào)用業(yè)務(wù)層
UserService userService = new UserServiceImpl();
// 如果修改成功贿讹,返回true
flag = userService.updatePwd(((User) o).getId(), newpassword);
if (flag) {
// 設(shè)置屬性:返回前端
req.setAttribute("message", "修改密碼成功渐逃,請退出,使用新密碼登錄");
// 移除session
req.getSession().removeAttribute(Constants.USER_SESSION);
} else {
// 密碼修改失敗
req.setAttribute("message", "修改密碼失敗");
}
} else {
// 密碼有問題
req.setAttribute("message", "密碼有問題");
}
try {
resp.sendRedirect(req.getContextPath() + "/jsp/pwdmodify.jsp");
} catch (IOException e) {
e.printStackTrace();
}
}
- 注冊 servlet:
web.xml
中或注解方式@WebServlet("/jsp/user.do")
民褂;
4.4 使用 Ajax 優(yōu)化密碼修改
-
Json 轉(zhuǎn)換依賴:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.79</version> </dependency>
在
UserServlet
中創(chuàng)建toJson
方法:
/**
* 轉(zhuǎn)換為Json類型
*
* @param resp
* @param object 需要轉(zhuǎn)換的對象
*/
private void toJson(HttpServletResponse resp, Object object) {
// 返回json類型
resp.setContentType("application/json");
try {
// 輸出流
PrintWriter writer = resp.getWriter();
// JSONArray工具類茄菊,轉(zhuǎn)換格式
// 將結(jié)果集,以json格式返回
writer.write(JSONArray.toJSONString(object));
// 刷新
writer.flush();
// 關(guān)閉流
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
- 編寫驗(yàn)證舊密碼的 Servlet 類(方法復(fù)用):
UserServlet
中增加
// doGet 方法中添加
// 驗(yàn)證舊密碼
else if (method.equals("pwdmodify") && method != null) {
this.pwdModify(req, resp);
}
// 在doGet外添加復(fù)用方法
/**
* Ajax驗(yàn)證舊密碼:與session中的密碼比對
*
* @param req
* @param resp
*/
private void pwdModify(HttpServletRequest req, HttpServletResponse resp) {
// 獲取session
Object o = req.getSession().getAttribute(Constants.USER_SESSION);
String oldpassword = req.getParameter("oldpassword");
// 萬能的Map
Map<String, String> resultMap = new HashMap<>();
// Session過期
if (o == null) {
resultMap.put("result", "sessionerror");
// 密碼為空
} else if (StringUtils.isNullOrEmpty(oldpassword)) {
resultMap.put("result", "error");
// 密碼不正確
} else {
// session中的用戶密碼
String userPassword = ((User) o).getUserPassword();
if (userPassword.equals(oldpassword)) {
resultMap.put("result", "true");
} else {
resultMap.put("result", "false");
}
}
// 轉(zhuǎn)換為json類型
this.toJson(resp, resultMap);
}
五赊堪、用戶管理模塊
-
結(jié)構(gòu)流程圖:
導(dǎo)入分頁的工具類:
PageSupport.java
// 分頁工具類
public class PageSupport {
//當(dāng)前頁碼-來自于用戶輸入
private int currentPageNo = 1;
//總數(shù)量(表)
private int totalCount = 0;
//頁面容量
private int pageSize = 0;
//總頁數(shù)-totalCount/pageSize(+1)
private int totalPageCount = 1;
public int getCurrentPageNo() {
return currentPageNo;
}
// OOP三大特性:封裝(屬性私有面殖、get/set、在set中限定一些不安全情況)
public void setCurrentPageNo(int currentPageNo) {
if (currentPageNo > 0) {
this.currentPageNo = currentPageNo;
}
}
public int getTotalCount() {
return totalCount;
}
/**
* 設(shè)置總記錄數(shù)哭廉,獲取頁面總數(shù)
*
* @param totalCount
*/
public void setTotalCount(int totalCount) {
if (totalCount > 0) {
this.totalCount = totalCount;
//設(shè)置總頁數(shù)
this.setTotalPageCountByRs();
}
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
if (pageSize > 0) {
this.pageSize = pageSize;
}
}
// 獲取頁面總數(shù)
public int getTotalPageCount() {
return totalPageCount;
}
public void setTotalPageCount(int totalPageCount) {
this.totalPageCount = totalPageCount;
}
/**
* 通過查詢記錄數(shù)脊僚,計(jì)算頁面總數(shù)
*/
public void setTotalPageCountByRs() {
if (this.totalCount % this.pageSize == 0) {
this.totalPageCount = this.totalCount / this.pageSize;
} else if (this.totalCount % this.pageSize > 0) {
this.totalPageCount = this.totalCount / this.pageSize + 1;
} else {
this.totalPageCount = 0;
}
}
}
導(dǎo)入用戶列表及相關(guān)
jsp
文件:-
按照自底向上的流程,編寫:
- Dao
- DaoImpl
- Service
- ServiceImpl
- Servlet
5.1 獲取用戶的數(shù)量
-
UserDao
接口遵绰,添加方法:
/**
* 查詢用戶總數(shù)
*
* @param connection 數(shù)據(jù)庫連接對象
* @param userName 用戶名
* @param userRole 用戶角色
* @return int
* @throws SQLException
*/
public int getUserCount(Connection connection, String userName, int userRole) throws SQLException;
-
UserDaoImpl
中添加實(shí)現(xiàn)方法:
/**
* 根據(jù)用戶名或角色辽幌,查詢總數(shù)
*
* @param connection 數(shù)據(jù)庫連接對象
* @param userName 用戶名
* @param userRole 用戶角色
* @return count
* @throws SQLException
*/
@Override
public int getUserCount(Connection connection, String userName, int userRole) throws SQLException {
PreparedStatement pstm = null;
ResultSet rs = null;
int count = 0;
if (connection != null) {
StringBuffer sql = new StringBuffer();
sql.append("select count(1) as count from `smbms_user` u,`smbms_role` r where u.`userRole`=r.`id`");
// 存放參數(shù)
ArrayList<Object> list = new ArrayList<>();
if (!StringUtils.isNullOrEmpty(userName)) {
sql.append(" and u.`userName` like ?");
// index[0]
list.add("%" + userName + "%");
}
if (userRole > 0) {
sql.append(" and u.`userRole` = ?");
// index[1]
list.add(userRole);
}
// List 轉(zhuǎn)換為數(shù)組
Object[] params = list.toArray();
System.out.println("UserDaoImpl-->getUserCount:" + sql.toString());
rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
if (rs.next()) {
// 從結(jié)果集中獲取最終的數(shù)量
count = rs.getInt("count");
}
BaseDao.closeResource(null, pstm, rs);
}
return count;
}
-
UserService
接口中,添加方法:
// 查詢用戶數(shù)
public int getUserCount(String userName, int userRole);
-
UserServiceImpl
實(shí)現(xiàn)方法:
/**
* 查詢用戶數(shù)
*
* @param userName 用戶名
* @param userRole 角色名
* @return count
*/
@Override
public int getUserCount(String userName, int userRole) {
Connection connection = null;
int count = 0;
try {
connection = BaseDao.getConnection();
count = userDao.getUserCount(connection, userName, userRole);
} catch (SQLException e) {
e.printStackTrace();
} finally {
BaseDao.closeResource(connection, null, null);
}
return count;
}
5.2 通過條件查詢用戶列表
-
UserDao
接口椿访,添加方法:
/**
* 通過條件查詢用戶列表
*
* @param connection 數(shù)據(jù)庫連接對象
* @param userName 用戶名
* @param userRole 用戶角色
* @param currentPageNo 當(dāng)前頁
* @param pageSize 頁面大小
* @return List<User>
* @throws SQLException
*/
public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize) throws SQLException;
-
UserDaoImpl
中添加實(shí)現(xiàn)方法:
/**
* 通過條件查詢用戶列表
*
* @param connection 數(shù)據(jù)庫連接對象
* @param userName 用戶名
* @param userRole 用戶角色
* @param currentPageNo 當(dāng)前頁
* @param pageSize 頁面大小
* @return List<User>
*/
@Override
public List<User> getUserList(Connection connection, String userName, int userRole,
int currentPageNo, int pageSize) throws SQLException {
PreparedStatement pstm = null;
ResultSet rs = null;
// 用戶列表
List<User> userList = new ArrayList<>();
if (connection != null) {
StringBuffer sql = new StringBuffer();
sql.append("SELECT u.*,r.`roleName` userRoleName FROM `smbms_user` u INNER JOIN `smbms_role` r ON u.`userRole`=r.`id`");
ArrayList<Object> list = new ArrayList<>();
if (!StringUtils.isNullOrEmpty(userName)) {
sql.append(" and u.`userName` like ?");
// index[0]
list.add("%" + userName + "%");
}
if (userRole > 0) {
sql.append(" and u.`userRole` = ?");
// index[1]
list.add(userRole);
}
// 分頁
sql.append(" ORDER BY `creationDate` DESC LIMIT ?,?");
// 當(dāng)前頁
currentPageNo = (currentPageNo - 1) * pageSize;
list.add(currentPageNo);
list.add(pageSize);
// List 轉(zhuǎn)換為數(shù)組
Object[] params = list.toArray();
System.out.println("UserDaoImpl-->getUserCount:" + sql.toString());
rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
while (rs.next()) {
User _user = new User();
_user.setId(rs.getInt("id"));
_user.setUserCode(rs.getString("userCode"));
_user.setUserName(rs.getString("userName"));
_user.setGender(rs.getInt("gender"));
_user.setBirthday(rs.getDate("birthday"));
_user.setPhone(rs.getString("phone"));
_user.setUserRole(rs.getInt("userRole"));
_user.setUserRoleName(rs.getString("userRoleName"));
userList.add(_user);
}
BaseDao.closeResource(null, pstm, rs);
}
return userList;
}
-
UserService
接口中乌企,添加方法:
// 根據(jù)條件查詢用戶列表
public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize);
-
UserServiceImpl
實(shí)現(xiàn)方法:
/**
* 根據(jù)條件查詢用戶列表
*
* @param queryUserName 用戶名
* @param queryUserRole 用戶角色
* @param currentPageNo 當(dāng)前頁
* @param pageSize 頁面大小
* @return List<User>
*/
@Override
public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize) {
Connection connection = null;
List<User> userList = null;
try {
connection = BaseDao.getConnection();
userList = userDao.getUserList(connection, queryUserName, queryUserRole, currentPageNo, pageSize);
} catch (SQLException e) {
e.printStackTrace();
} finally {
BaseDao.closeResource(connection, null, null);
}
return userList;
}
5.3 獲取用戶角色列表
- 在
dao
包下新建role
目錄,創(chuàng)建RoleDao
接口:
public interface RoleDao {
// 獲取角色列表
public List<Role> getRoleList(Connection connection) throws SQLException;
}
- 創(chuàng)建
RoleDaoImpl
實(shí)現(xiàn)類:
public class RoleDaoImpl implements RoleDao {
/**
* 獲取角色列表
*
* @param connection 數(shù)據(jù)庫連接對象
* @return List<Role>
* @throws SQLException
*/
@Override
public List<Role> getRoleList(Connection connection) throws SQLException {
PreparedStatement pstm = null;
ResultSet rs = null;
// 創(chuàng)建角色列表
ArrayList<Role> roleList = new ArrayList<>();
if (connection != null) {
String sql = "select * from `smbms_role`";
Object[] params = {};
rs = BaseDao.execute(connection, pstm, rs, sql, params);
while (rs.next()) {
Role _role = new Role();
_role.setId(rs.getInt("id"));
_role.setRoleCode(rs.getString("roleCode"));
_role.setRoleName(rs.getString("roleName"));
roleList.add(_role);
}
BaseDao.closeResource(null, pstm, rs);
}
return roleList;
}
}
- 在
service
包下成玫,新建role
目錄加酵,創(chuàng)建RoleService
接口:
public interface RoleService {
// 獲取角色列表
public List<Role> getRoleList();
}
- 創(chuàng)建
RoleServiceImpl
實(shí)現(xiàn)類,實(shí)現(xiàn)方法:- 調(diào)用
dao
層哭当,需要先引入猪腕;
- 調(diào)用
public class RoleServiceImpl implements RoleService {
// 引入dao
private RoleDao roleDao;
public RoleServiceImpl() {
roleDao = new RoleDaoImpl();
}
/**
* 獲取角色列表
*
* @return List<Role>
*/
@Override
public List<Role> getRoleList() {
Connection connection = null;
// 創(chuàng)建角色列表
List<Role> roleList = null;
try {
connection = BaseDao.getConnection();
// 獲取角色列表
roleList = roleDao.getRoleList(connection);
} catch (SQLException e) {
e.printStackTrace();
} finally {
BaseDao.closeResource(connection, null, null);
}
return roleList;
}
}
5.4 查詢模塊的 Servlet
-
UserServlet
中添加:
// doGet 方法中添加
// 用戶管理
else if (method.equals("query") && method != null) {
this.query(req, resp);
}
/**
* 用戶管理(重點(diǎn),難點(diǎn)):查詢
*
* @param req
* @param resp
*/
private void query(HttpServletRequest req, HttpServletResponse resp) {
// 查詢用戶列表
// 從前端獲取數(shù)據(jù)
String queryUserName = req.getParameter("queryname");
String temp = req.getParameter("queryUserRole");
String pageIndex = req.getParameter("pageIndex");
// 設(shè)置默認(rèn)的用戶角色碼荣病,避免temp為空
int queryUserRole = 0;
// 獲取用戶列表
UserService userService = new UserServiceImpl();
List<User> userList = null;
// 第一次請求码撰,一定是第一頁渗柿,頁面大小固定
// 頁面大懈雠琛:可以寫配置文件脖岛,方便以后修改
int pageSize = 5;
// 默認(rèn)起始頁面
int currentPageNo = 1;
if (queryUserName == null) {
queryUserName = "";
}
if (temp != null && !temp.equals("")) {
// 給查詢賦值 0、1颊亮、2柴梆、3
queryUserRole = Integer.parseInt(temp);
}
if (pageIndex != null) {
try {
currentPageNo = Integer.parseInt(pageIndex);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
// 獲取用戶的總數(shù)(分頁:上一頁、下一頁)
int totalCount = userService.getUserCount(queryUserName, queryUserRole);
// 總頁數(shù)支持
PageSupport pageSupport = new PageSupport();
pageSupport.setCurrentPageNo(currentPageNo);
pageSupport.setPageSize(pageSize);
// 通過查詢記錄總數(shù)终惑,計(jì)算總頁面數(shù)
pageSupport.setTotalCount(totalCount);
// 控制首頁和尾頁
// 總頁面數(shù)
int totalPageCount = pageSupport.getTotalPageCount();
// 如果當(dāng)前頁面小于1绍在,就顯示第一頁
if (currentPageNo < 1) {
currentPageNo = 1;
// 如果當(dāng)前頁面大于最后一頁,就顯示最后一頁
} else if (currentPageNo > totalPageCount) {
currentPageNo = totalPageCount;
}
// 獲取用戶列表展示
userList = userService.getUserList(queryUserName, queryUserRole, currentPageNo, pageSize);
// 把用戶列表傳遞給前端
req.setAttribute("userList", userList);
// 獲取角色列表
RoleServiceImpl roleService = new RoleServiceImpl();
List<Role> roleList = roleService.getRoleList();
// 把角色列表傳遞給前端
req.setAttribute("roleList", roleList);
// 給前端傳遞其它屬性
req.setAttribute("totalCount", totalCount);
req.setAttribute("currentPageNo", currentPageNo);
req.setAttribute("totalPageCount", totalPageCount);
req.setAttribute("queryUserName", queryUserName);
req.setAttribute("queryUserRole", queryUserRole);
// 返回前端頁面
try {
req.getRequestDispatcher("userlist.jsp").forward(req, resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
5.5 用戶管理模塊的增雹有、刪偿渡、改、查(查看)
-
UserDao
中添加:
/**
* 添加用戶
*
* @param connection 數(shù)據(jù)庫連接對象
* @param user 用戶對象
* @return updateRows
* @throws SQLException
*/
public int add(Connection connection, User user) throws SQLException;
// 根據(jù)id查看用戶
public User getUserById(Connection connection, int id) throws SQLException;
// 修改用戶信息
public int modify(Connection connection, User user) throws SQLException;
// 刪除用戶
public int delUser(Connection connection, int id) throws SQLException;
-
UserDaoImpl
中添加:
/**
* 添加用戶
*
* @param connection 數(shù)據(jù)庫連接對象
* @param user 用戶對象
* @return updateRows
* @throws SQLException
*/
@Override
public int add(Connection connection, User user) throws SQLException {
PreparedStatement pstm = null;
int updateRows = 0;
if (connection != null) {
String sql = "INSERT INTO `smbms_user` (`userCode`,`userName`,`userPassword`," +
"`gender`,`birthday`,`phone`,`address`,`userRole`,`createdBy`," +
"`creationDate`) VALUE (?,?,?,?,?,?,?,?,?,?)";
Object[] params = {user.getUserCode(), user.getUserName(), user.getUserPassword(),
user.getGender(), user.getBirthday(), user.getPhone(), user.getAddress(),
user.getUserRole(), user.getCreatedBy(), user.getCreationDate()};
updateRows = BaseDao.execute(connection, pstm, sql, params);
BaseDao.closeResource(null, pstm, null);
}
return updateRows;
}
/**
* 根據(jù)id查看用戶
*
* @param connection 數(shù)據(jù)庫連接對象
* @param id 用戶id
* @return User
* @throws SQLException
*/
@Override
public User getUserById(Connection connection, int id) throws SQLException {
PreparedStatement pstm = null;
ResultSet rs = null;
User _user = null;
if (connection != null) {
String sql = "SELECT u.*,`roleName` userRoleName FROM `smbms_user` u " +
"INNER JOIN `smbms_role` r ON u.`userRole`= r.`id` WHERE u.`id`=?";
Object[] params = {id};
rs = BaseDao.execute(connection, pstm, rs, sql, params);
while (rs.next()) {
_user = new User();
// id必須添加霸奕,否則修改時無法獲取id
_user.setId(rs.getInt("id"));
_user.setUserCode(rs.getString("userCode"));
_user.setUserName(rs.getString("userName"));
_user.setGender(rs.getInt("gender"));
_user.setBirthday(rs.getDate("birthday"));
_user.setPhone(rs.getString("phone"));
_user.setAddress(rs.getString("address"));
_user.setUserRole(rs.getInt("userRole"));
_user.setUserRoleName(rs.getString("userRoleName"));
}
BaseDao.closeResource(null, pstm, rs);
}
return _user;
}
/**
* 修改用戶信息
*
* @param connection 數(shù)據(jù)庫連接對象
* @param user 用戶對象
* @return updateRows
* @throws SQLException
*/
@Override
public int modify(Connection connection, User user) throws SQLException {
PreparedStatement pstm = null;
int updateRows = 0;
if (connection != null) {
String sql = "UPDATE `smbms_user` SET `userName`=?,`gender`=?,`birthday`=?," +
"`phone`=?,`address`=?,`userRole`=?,`modifyBy`=?,`modifyDate`=? WHERE `id`=?";
Object[] params = {user.getUserName(), user.getGender(), user.getBirthday(),
user.getPhone(), user.getAddress(), user.getUserRole(),
user.getModifyBy(), user.getModifyDate(), user.getId()};
updateRows = BaseDao.execute(connection, pstm, sql, params);
BaseDao.closeResource(null, pstm, null);
}
return updateRows;
}
// 刪除用戶
@Override
public int delUser(Connection connection, int id) throws SQLException {
PreparedStatement pstm = null;
int updateRows = 0;
if (connection != null) {
String sql = "DELETE FROM `smbms_user` WHERE `id`=?";
Object[] params = {id};
updateRows = BaseDao.execute(connection, pstm, sql, params);
BaseDao.closeResource(null, pstm, null);
}
return updateRows;
}
- UserService 中添加:
// 添加用戶
public boolean add(User user);
// 查詢用戶編碼:用戶登錄login溜宽,也可以實(shí)現(xiàn)功能
public User selectUserCodeExist(String userCode) throws SQLException;
// 根據(jù)id查看用戶
public User getUserById(int id);
// 修改用戶信息
public boolean modify(User user);
// 刪除用戶
public boolean delUser(int id);
-
UserServiceImpl
里添加:
/**
* 添加用戶
*
* @param user 用戶對象
* @return boolean
*/
@Override
public boolean add(User user) {
boolean flag = false;
Connection connection = null;
try {
connection = BaseDao.getConnection();
// 開啟事務(wù)
connection.setAutoCommit(false);
int updateRows = userDao.add(connection, user);
// 提交事務(wù)
connection.commit();
if (updateRows > 0) {
flag = true;
System.out.println("用戶添加成功");
} else {
System.out.println("用戶添加失敗");
}
} catch (SQLException e) {
e.printStackTrace();
try {
System.out.println("rollback==========");
// 手動通知,事務(wù)回滾(可去掉质帅,失敗后自動回滾)
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
} finally {
BaseDao.closeResource(connection, null, null);
}
return flag;
}
/**
* 查詢用戶編碼是否存在:與login功能相同适揉,可以通用
*
* @param userCode 用戶編碼
* @return User
*/
@Override
public User selectUserCodeExist(String userCode) {
Connection connection = null;
User user = null;
try {
connection = BaseDao.getConnection();
user = userDao.getLoginUser(connection, userCode);
} catch (SQLException e) {
e.printStackTrace();
} finally {
BaseDao.closeResource(connection, null, null);
}
return user;
}
/**
* 根據(jù)id查看用戶
*
* @param id 用戶id
* @return 用戶對象
*/
@Override
public User getUserById(int id) {
Connection connection = null;
User user = null;
try {
connection = BaseDao.getConnection();
user = userDao.getUserById(connection, id);
} catch (SQLException e) {
e.printStackTrace();
} finally {
BaseDao.closeResource(connection, null, null);
}
return user;
}
/**
* 修改用戶信息
*
* @param user 用戶對象
* @return boolean
*/
@Override
public boolean modify(User user) {
boolean flag = false;
Connection connection = null;
try {
connection = BaseDao.getConnection();
// 開啟事務(wù)
connection.setAutoCommit(false);
int updateRows = userDao.modify(connection, user);
// 提交事務(wù)
connection.commit();
if (updateRows > 0) {
flag = true;
}
} catch (SQLException e) {
e.printStackTrace();
try {
// 手動通知事務(wù)回滾
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
} finally {
BaseDao.closeResource(connection, null, null);
}
return flag;
}
/**
* 刪除用戶
*
* @param id 用戶id
* @return boolean
*/
@Override
public boolean delUser(int id) {
boolean flag = false;
Connection connection = null;
try {
connection = BaseDao.getConnection();
// 開啟事務(wù)
connection.setAutoCommit(false);
int updateRows = userDao.delUser(connection, id);
// 提交事務(wù)
connection.commit();
if (updateRows > 0) {
flag = true;
}
} catch (SQLException e) {
e.printStackTrace();
try {
// 手動通知事務(wù)回滾
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
} finally {
BaseDao.closeResource(connection, null, null);
}
return flag;
}
-
UserServlet
整合文件:
// 通過注解方式,注冊servlet
@WebServlet("/jsp/user.do")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 實(shí)現(xiàn)servlet復(fù)用
String method = req.getParameter("method");
// 修改密碼
if (method.equals("savepwd") && method != null) {
this.updatePwd(req, resp);
// 驗(yàn)證舊密碼
} else if (method.equals("pwdmodify") && method != null) {
this.pwdModify(req, resp);
// 用戶管理
} else if (method.equals("query") && method != null) {
this.query(req, resp);
// 添加用戶
} else if (method.equals("add") && method != null) {
this.add(req, resp);
// 角色列表:添加用戶時需獲取
} else if (method.equals("getrolelist") && method != null) {
this.getRoleList(req, resp);
// 查看用戶編碼是否重復(fù)
} else if (method.equals("ucexist") && method != null) {
this.userCodeExist(req, resp);
// 查看用戶
} else if (method.equals("view") && method != null) {
this.getUserById(req, resp, "userview.jsp");
// 修改用戶
} else if (method.equals("modify") && method != null) {
this.getUserById(req, resp, "usermodify.jsp");
// 修改確認(rèn)
} else if (method.equals("modifyexe") && method != null) {
this.modify(req, resp);
// 刪除用戶
} else if (method.equals("deluser") && method != null) {
this.delUser(req, resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
/**
* 修改密碼
*
* @param req
* @param resp
*/
private void updatePwd(HttpServletRequest req, HttpServletResponse resp) {
// 獲取session
Object o = req.getSession().getAttribute(Constants.USER_SESSION);
String newpassword = req.getParameter("newpassword");
// 設(shè)置標(biāo)志位
boolean flag = false;
if (o != null && newpassword != null && newpassword.length() != 0) {
// 調(diào)用業(yè)務(wù)層
UserService userService = new UserServiceImpl();
// 如果修改成功煤惩,返回true
flag = userService.updatePwd(((User) o).getId(), newpassword);
if (flag) {
// 設(shè)置屬性:返回前端
req.setAttribute("message", "修改密碼成功嫉嘀,請退出,使用新密碼登錄");
// 移除session
req.getSession().removeAttribute(Constants.USER_SESSION);
} else {
// 密碼修改失敗
req.setAttribute("message", "修改密碼失敗");
}
} else {
// 密碼有問題
req.setAttribute("message", "密碼有問題");
}
try {
resp.sendRedirect(req.getContextPath() + "/jsp/pwdmodify.jsp");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Ajax驗(yàn)證舊密碼:與session中的密碼比對
*
* @param req
* @param resp
*/
private void pwdModify(HttpServletRequest req, HttpServletResponse resp) {
// 獲取session
Object o = req.getSession().getAttribute(Constants.USER_SESSION);
String oldpassword = req.getParameter("oldpassword");
// 萬能的Map
Map<String, String> resultMap = new HashMap<>();
// Session過期
if (o == null) {
resultMap.put("result", "sessionerror");
// 密碼為空
} else if (StringUtils.isNullOrEmpty(oldpassword)) {
resultMap.put("result", "error");
// 密碼不正確
} else {
// session中的用戶密碼
String userPassword = ((User) o).getUserPassword();
if (userPassword.equals(oldpassword)) {
resultMap.put("result", "true");
} else {
resultMap.put("result", "false");
}
}
// 轉(zhuǎn)換為json類型
this.toJson(resp, resultMap);
}
/**
* 用戶管理(重點(diǎn)魄揉,難點(diǎn)):查詢
*
* @param req
* @param resp
*/
private void query(HttpServletRequest req, HttpServletResponse resp) {
// 查詢用戶列表
// 從前端獲取數(shù)據(jù)
String queryUserName = req.getParameter("queryname");
String temp = req.getParameter("queryUserRole");
String pageIndex = req.getParameter("pageIndex");
// 設(shè)置默認(rèn)的用戶角色碼剪侮,避免temp為空
int queryUserRole = 0;
// 獲取用戶列表
UserService userService = new UserServiceImpl();
List<User> userList = null;
// 第一次請求,一定是第一頁什猖,頁面大小固定
// 頁面大衅北搿:可以寫配置文件,方便以后修改
int pageSize = 5;
// 默認(rèn)起始頁面
int currentPageNo = 1;
if (queryUserName == null) {
queryUserName = "";
}
if (temp != null && !temp.equals("")) {
// 給查詢賦值 0不狮、1降铸、2、3
queryUserRole = Integer.parseInt(temp);
}
if (pageIndex != null) {
try {
currentPageNo = Integer.parseInt(pageIndex);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
// 獲取用戶的總數(shù)(分頁:上一頁摇零、下一頁)
int totalCount = userService.getUserCount(queryUserName, queryUserRole);
// 總頁數(shù)支持
PageSupport pageSupport = new PageSupport();
pageSupport.setCurrentPageNo(currentPageNo);
pageSupport.setPageSize(pageSize);
// 通過查詢記錄總數(shù)推掸,計(jì)算總頁面數(shù)
pageSupport.setTotalCount(totalCount);
// 控制首頁和尾頁
// 總頁面數(shù)
int totalPageCount = pageSupport.getTotalPageCount();
// 如果當(dāng)前頁面小于1,就顯示第一頁
if (currentPageNo < 1) {
currentPageNo = 1;
// 如果當(dāng)前頁面大于最后一頁驻仅,就顯示最后一頁
} else if (currentPageNo > totalPageCount) {
currentPageNo = totalPageCount;
}
// 獲取用戶列表展示
userList = userService.getUserList(queryUserName, queryUserRole, currentPageNo, pageSize);
// 把用戶列表傳遞給前端
req.setAttribute("userList", userList);
// 獲取角色列表
RoleServiceImpl roleService = new RoleServiceImpl();
List<Role> roleList = roleService.getRoleList();
// 把角色列表傳遞給前端
req.setAttribute("roleList", roleList);
// 給前端傳遞其它屬性
req.setAttribute("totalCount", totalCount);
req.setAttribute("currentPageNo", currentPageNo);
req.setAttribute("totalPageCount", totalPageCount);
req.setAttribute("queryUserName", queryUserName);
req.setAttribute("queryUserRole", queryUserRole);
// 返回前端頁面
try {
req.getRequestDispatcher("userlist.jsp").forward(req, resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 添加用戶:(需先獲取角色列表)
*
* @param req
* @param resp
* @throws IOException
* @throws ServletException
*/
private void add(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
// 從前端獲取屬性
String userCode = req.getParameter("userCode");
String userName = req.getParameter("userName");
String userPassword = req.getParameter("userPassword");
String gender = (req.getParameter("gender"));
String birthday = req.getParameter("birthday");
String phone = req.getParameter("phone");
String address = req.getParameter("address");
String userRole = req.getParameter("userRole");
// 創(chuàng)建用戶對象谅畅,將前端的值存儲到對象中
User user = new User();
user.setUserCode(userCode);
user.setUserName(userName);
user.setUserPassword(userPassword);
user.setGender(Integer.valueOf(gender));
try {
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(birthday));
} catch (ParseException e) {
e.printStackTrace();
}
user.setPhone(phone);
user.setAddress(address);
user.setUserRole(Integer.valueOf(userRole));
user.setCreationDate(new Date());
user.setCreatedBy(((User) req.getSession().getAttribute(Constants.USER_SESSION)).getId());
// 調(diào)用業(yè)務(wù)層
UserService userService = new UserServiceImpl();
if (userService.add(user)) {
resp.sendRedirect(req.getContextPath() + "/jsp/user.do?method=query");
} else {
req.getRequestDispatcher("useradd.jsp").forward(req, resp);
}
}
/**
* 獲取角色列表
*
* @param req
* @param resp
* @throws IOException
*/
private void getRoleList(HttpServletRequest req, HttpServletResponse resp) {
List<Role> roleList = null;
RoleService roleService = new RoleServiceImpl();
roleList = roleService.getRoleList();
// 把roleList轉(zhuǎn)換成json對象輸出
this.toJson(resp, roleList);
}
/**
* 查看用戶編碼是否重復(fù)
*
* @param req
* @param resp
* @throws IOException
*/
private void userCodeExist(HttpServletRequest req, HttpServletResponse resp) {
String userCode = req.getParameter("userCode");
Map<String, String> resultMap = new HashMap<>();
if (StringUtils.isNullOrEmpty(userCode)) {
resultMap.put("userCode", "exist");
} else {
UserService userService = new UserServiceImpl();
User user = null;
// 調(diào)用業(yè)務(wù)層
// user = userService.selectUserCodeExist(userCode);
// 業(yè)務(wù)層的login方法,功能相同
user = userService.login(userCode, null);
if (user != null) {
resultMap.put("userCode", "exist");
} else {
resultMap.put("userCode", "notexist");
}
}
// 轉(zhuǎn)換為Json
this.toJson(resp, resultMap);
}
/**
* 轉(zhuǎn)換為Json類型
*
* @param resp
* @param object 需要轉(zhuǎn)換的對象
*/
private void toJson(HttpServletResponse resp, Object object) {
// 返回json類型
resp.setContentType("application/json");
try {
// 輸出流
PrintWriter writer = resp.getWriter();
// JSONArray工具類噪服,轉(zhuǎn)換格式
// 將結(jié)果集毡泻,以json格式返回
writer.write(JSONArray.toJSONString(object));
// 刷新
writer.flush();
// 關(guān)閉流
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根據(jù)id查看用戶
*
* @param req
* @param resp
* @param url 跳轉(zhuǎn)網(wǎng)頁地址
* @throws ServletException
* @throws IOException
*/
private void getUserById(HttpServletRequest req, HttpServletResponse resp, String url) throws ServletException, IOException {
String id = req.getParameter("uid");
// id不為空
if (!StringUtils.isNullOrEmpty(id)) {
UserService userService = new UserServiceImpl();
User user = userService.getUserById(Integer.parseInt(id));
req.setAttribute("user", user);
req.getRequestDispatcher(url).forward(req, resp);
}
}
/**
* 修改用戶信息
*
* @param req
* @param resp
*/
private void modify(HttpServletRequest req, HttpServletResponse resp) {
String id = req.getParameter("uid");
String userName = req.getParameter("userName");
String gender = req.getParameter("gender");
String birthday = req.getParameter("birthday");
String phone = req.getParameter("phone");
String address = req.getParameter("address");
String userRole = req.getParameter("userRole");
User user = new User();
user.setId(Integer.valueOf(id));
user.setUserName(userName);
user.setGender(Integer.valueOf(gender));
try {
user.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse(birthday));
} catch (ParseException e) {
e.printStackTrace();
}
user.setPhone(phone);
user.setAddress(address);
user.setUserRole(Integer.valueOf(userRole));
user.setModifyBy(((User) req.getSession().getAttribute(Constants.USER_SESSION)).getId());
user.setModifyDate(new Date());
UserService userService = new UserServiceImpl();
if (userService.modify(user)) {
try {
resp.sendRedirect(req.getContextPath() + "/jsp/user.do?method=query");
} catch (IOException e) {
e.printStackTrace();
}
} else {
try {
req.getRequestDispatcher("usermodify.jsp").forward(req, resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 刪除用戶
private void delUser(HttpServletRequest req, HttpServletResponse resp) {
String id = req.getParameter("uid");
Map<String, String> resultMap = new HashMap<>();
if (StringUtils.isNullOrEmpty(id)) {
resultMap.put("delResult", "notexist");
} else {
UserService userService = new UserServiceImpl();
if (userService.delUser(Integer.parseInt(id))) {
resultMap.put("delResult", "true");
} else {
resultMap.put("delResult", "false");
}
}
// 轉(zhuǎn)換為Json
this.toJson(resp, resultMap);
}
}
六、其它模塊
參照用戶模塊
項(xiàng)目流程圖