狂神說Java【SMBMS】——SMBMS超市訂單管理系統(四) ——密碼修改


​ 分析:很明顯,要修改用戶密碼我們還是需要和數據庫交互,那么就還是前面我們寫登陸功能的代碼編寫步驟 —— DAO層、service層、servlet層,前端頁面直接使用現成的,但是注意servlet中使用的地址和servlet的地址映射注意和前端頁面保持一致

為什么要按照DAO層、service層、servlet層,JSP頁面的順序來編寫呢?

​ 原因在上圖展示的很清楚,開發JSP需要填寫servlet在服務器上的映射路徑,開發servlet需要調用service中的方法完成業務邏輯,開發service需要調用Dao中對數據庫的操作來操作數據庫,而只有Dao中使用的JDBC我們是數據庫廠商實現了的,所以我們可以直接使用;所以為了開發的完整性,我們就應該從Dao開始-->service-->servlet-->JSP

分析實現步驟/模塊功能划分(很重要)

​ 只有我們先想好了怎么做,然后再去編寫代碼才會快,且有條不紊,切忌看完要求之后馬上開始寫代碼

1.導入前端素材


2.Dao接口

package com.thhh.dao.user;

import com.thhh.pojo.User;

import java.sql.Connection;

public interface UserDao {
    /**
     * 得到要進行登陸的用戶
     * @param conn:數據庫連接對象
     * @param userCode:通過用戶的用戶名userCode查詢用戶數據
     * @return
     */
    public User getLoginUserInfo(Connection conn,String userCode);

    /**
     * 修改用戶密碼
     * @param conn:數據庫連接對象
     * @param id:修改密碼的用戶的ID
     * @param newPwd:新密碼
     * @return:影響行數
     */
    public int updatePwd(Connection conn,String newPwd,int id);
}

​ 只需要看方法2

3.Dao接口實現

package com.thhh.dao.user;

import com.thhh.dao.BaseDao;
import com.thhh.pojo.User;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UserDaoImpl implements UserDao{
    //1、獲取要進行登陸的用戶對象
    @Override
    public User getLoginUserInfo(Connection conn, String userCode) {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        User user = null;
        if (conn!=null){
            String sql = "SELECT * FROM smbms_user WHERE userCode = ?";
            Object[] params = {userCode};
            rs = BaseDao.executeQuery(sql,params,conn,pstmt,rs);//調用項目搭建階段准備的公共查詢方法
            try {
                    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"));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.close(null,pstmt,rs);//因為數據庫的連接可能不只是這一個操作,所以我們不應該做完一件事就把數據庫連接對象銷毀,所以conn處傳的null
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        return user;
    }

    //2、修改用戶密碼
    @Override
    public int updatePwd(Connection conn, String newPwd, int id) {
        PreparedStatement pstmt = null;
        int rs = 0;
        User user = null;
        if (conn!=null){
            String sql = "UPDATE smbms_user SET userPassword = ? WHERE id = ?";
            Object[] params = {newPwd,id};//按照sql語句的占位符的順序來傳遞數據,使用的時候需要注意
            rs = BaseDao.executeUpdate(sql,params,conn,pstmt);
            BaseDao.close(null,pstmt,null);//把這次使用的sql語句發送器關掉,連接不要關,service還可能有其他用
        }
        return rs;
    }
}

​ 只需要看方法2

4.service接口

package com.thhh.service.user;

import com.thhh.pojo.User;

import java.sql.Connection;

public interface UserService {
    /**
     * 1、獲取登陸用戶對象,對用戶登陸身份進行驗證
     * @param userCode:用戶賬號
     * @param userPassword:用戶密碼,注意,密碼判斷我們在service層進行;
     *                      在Dao層只是簡單的操作數據庫,沒有其他的邏輯代碼;在servlet層中只是接收和轉發請求以及控制視圖跳轉
     *                      而對於業務層(service)就是用來實現業務邏輯代碼的
     * @return
     */
    public User login(String userCode,String userPassword);

    /**
     * 2、根據用戶ID修改用戶密碼
     * @param newPwd:新密碼
     * @param id:用戶ID
     * @return
     */
    public boolean updatePwd(String newPwd, int id);
}

​ 只看方法2

5.service接口實現

package com.thhh.service.user;
/**
 * 業務層主要就是編寫業務代碼,在編寫業務代碼的時候經常會調用數據庫
 * 所以在業務層中需要使用到我們一開始編寫好的DAO的代碼
 */

import com.thhh.dao.BaseDao;
import com.thhh.dao.user.UserDao;
import com.thhh.dao.user.UserDaoImpl;
import com.thhh.pojo.User;

import java.sql.Connection;

public class UserServiceImpl implements UserService{
    private UserDao userDao;//業務層需要使用Dao,所以直接將Dao作為一個成員變量來使用

    public UserServiceImpl() {
        this.userDao = new UserDaoImpl();//在業務層被實例化的時候就讓它得到Dao對象,后面就可以直接去用
    }

    /**
     * 1、判斷登陸用戶的用戶名+密碼是否合法,並將用戶對象返回
     * @param userCode:用戶賬號
     * @param userPassword:用戶密碼,注意,密碼判斷我們在service層進行;
     *                      在Dao層只是簡單的操作數據庫,沒有其他的邏輯代碼;在servlet層中只是接收和轉發請求以及控制視圖跳轉
     *                      而對於業務層(service)就是用來實現業務邏輯代碼的
     * @return
     */
    @Override
    public User login(String userCode, String userPassword) {
        Connection conn = null;
        User user = null;
        User error = null;

        conn = BaseDao.getConnection();//獲取數據庫連接對象
        //通過業務層調用Dao層
        user = userDao.getLoginUserInfo(conn,userCode);//調用userDao中的獲取用戶信息的方法
        BaseDao.close(conn,null,null);
        if (user.getUserPassword().equals(userPassword)){
            return user;
        }

        return error;
    }

    /**
     *  2、通過已經登陸用戶的ID修改新密碼,並將數據庫中受影響的行數返回
     * @param newPwd:新密碼
     * @param id:用戶ID
     * @return
     */
    @Override
    public boolean updatePwd(String newPwd, int id) {
        Connection conn = null;
        int rs = 0;
        boolean flag = false;

        conn = BaseDao.getConnection();//獲取數據庫連接對象
        //通過業務層調用Dao層
        if (userDao.updatePwd(conn,newPwd,id)>0){//數據庫修改成功
            flag = true;
        }
        BaseDao.close(conn,null,null);

        return flag;
    }
}

​ 只看方法2

6.servlet編寫

package com.thhh.servlet.user;

import com.mysql.jdbc.StringUtils;
import com.thhh.pojo.User;
import com.thhh.service.user.UserService;
import com.thhh.service.user.UserServiceImpl;
import com.thhh.utils.Constants;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//實現servlet復用
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        boolean flag = false;

        Object user = req.getSession().getAttribute(Constants.USER_SESSION);
        String newpassword = req.getParameter("newpassword");

        if (user!=null && !StringUtils.isNullOrEmpty(newpassword)){//獲取到了這個用戶對象且獲取到的新密碼不為空
            UserService userService = new UserServiceImpl();
            flag = userService.updatePwd(newpassword,((User)user).getId());//servlet調用業務層
            if (flag){//修改成功
                req.setAttribute("message","密碼修改成功!請使用新密碼重新登陸");
                //移除用戶的session,利用過濾器阻止用戶再進行操作,直接跳轉error.jsp頁面
                req.getSession().removeAttribute(Constants.USER_SESSION);
            }else{
                req.setAttribute("message","密碼修改失敗");
            }
        }else {
            //用戶可以進行密碼修改,則user一定不是null,所以跳入這個分支的原因一定是newpassword = NULL
            req.setAttribute("message","密碼設置有誤,請重新輸入!");
        }
        //無論是修改成功還是失敗,都重定向到密碼修改頁面,就是在刷新頁面,否則我們設置在req中的message屬性不會被前端讀到
        req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

7.注冊servlet

<!--注冊用戶修改密碼的servlet-->
<servlet>
    <servlet-name>UserServlet</servlet-name>
    <servlet-class>com.thhh.servlet.user.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>UserServlet</servlet-name>
    <url-pattern>/jsp/user.do</url-pattern>
</servlet-mapping>

8.測試

​ bug1:

//1、在編寫servlet的時候,要判斷前端傳過來的新密碼是否為空,這里ZB用了一個工具類,但是這個工具類是isNullOrEmpty,即它的作用判斷"是空",所以使用的時候注意在前面加上一個"!"
//或者我們就是要常見的方法:newpassword!=null&&newpassword.length!=0

if (user!=null && !StringUtils.isNullOrEmpty(newpassword))

​ bug2:

//2、在編寫BaseDao即基本公共數據庫操作方法的時候,設置PreparedStatement對象中sql占位符的值時要注意
//PreparedStatement的占位符index從1開始,而數組的下標從0開始,所以我們使用的i=1,但是要注意控制循環次數的時候使用的是params.length,所以我們需要取"=",否則數組中的參數是取不完的,取不完就會出現SQL錯誤

for (int i=1;i<= params.length;i++){//循環遍歷參數數組,並將參數設入SQL中
    pstmt.setObject(i,params[i-1]);//注意:數組的index從0開始,而PreparedStatement中設置占位符的值的index從1開始
}

​ bug3:

//前端頁面上,編寫的時候要求輸入舊密碼,但是實際測試的時候輸入舊密碼有BUG,我們直接不使用輸入舊密碼,使用新密碼+重復新密碼輸入框來修改密碼
//但是前端使用的JS控制了提交表單的按鈕,即需要3個輸入框輸入都滿足要求的時候才能提交表單數據,所以我們需要把判斷舊密碼輸入框的判斷語句注釋了
//這樣才能只通過新密碼+重復新密碼實現密碼修改

saveBtn.on("click",function(){
   oldpassword.blur();
   newpassword.blur();
   rnewpassword.blur();
   // oldpassword.attr("validateStatus") == "true"
   // &&
   if( newpassword.attr("validateStatus") == "true"
      && rnewpassword.attr("validateStatus") == "true"){
      if(confirm("確定要修改密碼?")){
         $("#userForm").submit();
      }
   }
   
});






9.優化servlet代碼,實現servlet復用



通過測試,功能完全相同,且修改密碼正確!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM