登录页面 smbms项目 -- 狂神

本文详细介绍了Web应用的登录、注销功能的实现,包括Servlet、过滤器和DAO层的交互。同时,讨论了密码修改的流程,利用Ajax进行优化,以及用户管理的分页查询和角色操作。通过这些实践,提升了系统的用户体验和安全性。
摘要由CSDN通过智能技术生成

登录页面

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-be8AJ63P-1627137531598)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210707192833655.png)]

  1. 编写前端页面

  2. 设置首页(欢迎页面)

        <!--设置欢迎页面-->
        <welcome-file-list>
            <welcome-file>login.jsp</welcome-file>
        </welcome-file-list>
    
  3. 编写dao层 登录用户的接口

    //得到要登录的用户
        public User getLoginUser(Connection connection,String userCode) throws SQLException;
    }
    
  4. 编写dao接口的实现类

    public class UserDaoImpl implements UserDao{
        public User getLoginUser(Connection connection, String userCode) throws SQLException {
    
            PreparedStatement pstm = null;
            ResultSet rs = null;
            User user = null;
    
            if (connection != null) {
                String sql="select * from smbms_user where userCode=?";
                Object[] params = {userCode};//数组
    
                    rs = BaseDao.execute(connection, pstm, rs, sql, params);
                    if(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("createy"));
                        user.setCreationDate(rs.getTimestamp("creationDate"));
                        user.setModifyBy(rs.getInt("modifyBy"));
                        user.setModifyDate(rs.getTimestamp("modifyDate"));
                    }
                    BaseDao.closeResource(null,pstm,rs);
    
            }
    
            return user;
    
        }
    }
    
  5. 业务层接口

    public interface UserService {
        //用户登录
        public User login(String userCode,String password);
    
    }
    
  6. 业务层实现类

    public class UserServiceImpl implements UserService{
    
        //业务层都会调用dao层,所以我们要引入dao层 ;
        private UserDao userDao;
    
        public UserServiceImpl(){
            userDao = new UserDaoImpl();
        }
    
        public User login(String userCode, String password) {
            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;
        }
    
    }
    
    
  7. 编写Servlet

    package com.well.servlet.user;
    
    import com.well.pojo.User;
    import com.well.service.user.UserServiceImpl;
    import com.well.util.Constants;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class LoginServlet extends HttpServlet {
    
        //Servlet:控制层,调用业务层代码
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            System.out.println("LoginSerlet--start...");
    
            //获取用户名和密码
            String userCode = req.getParameter("userCode");
            String userPassword = req.getParameter("userPassword");
    
            //和数据库中的密码进行对比,调用业务层
            UserServiceImpl userService = new UserServiceImpl();
            User user = userService.login(userCode, userPassword); //这里已经把登录的人已经查出来了
    
            if (user != null) { //查有此人,可以登录
                //将用户的信息放到Session中
                req.getSession().setAttribute(Constants.USER_SESSION,user);
                //跳转到内部主页
                resp.sendRedirect("jsp/frame.jsp");
            }else {//查无此人 ,无法登录
                //转发会登录页面,顺便提示他,用户名或者密码错误;
                req.setAttribute("error","用户名或者密码不正确");
                req.getRequestDispatcher("login.jsp").forward(req,resp);
            }
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
    
  8. 注册Servlet

        <!--Servlet-->
        <servlet>
            <servlet-name>LoginServlet</servlet-name>
            <servlet-class>com.well.servlet.user.LoginServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>LoginServlet</servlet-name>
            <url-pattern>/login.do</url-pattern>
        </servlet-mapping>
    
  9. 测试访问,确保以上能成功!

登录功能优化

注销功能:

思路:移除Session,返回登录页面

public class LogoutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //移除用户的Constants.USER_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);
    }
}

注册xml

    <!--注销-->
    <servlet>
        <servlet-name>LogoutServler</servlet-name>
        <servlet-class>com.well.servlet.user.LogoutServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LogoutServler</servlet-name>
        <url-pattern>/jsp/logout.do</url-pattern>
    </servlet-mapping>

登录拦截优化

编写过滤器,并注册

package com.well.filter;

import com.well.pojo.User;
import com.well.util.Constants;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SysFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        //过滤器 从Session获取用户
        User user = (User) request.getSession().getAttribute(Constants.USER_SESSION);

        if (user == null) {//已经移除或者注销,或者未登录
            response.sendRedirect("/smbms/error.jsp");

        }else {
            chain.doFilter(req,resp);
        }


    }

    public void destroy() {

    }
}

注册过滤器

    <!--用户登录过滤器-->
    <filter>
        <filter-name>SysFilter</filter-name>
        <filter-class>com.well.filter.SysFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>SysFilter</filter-name>
        <url-pattern>/jsp/*</url-pattern>
    </filter-mapping>

测试,登录,注销,权限,都要保证OK!

密码修改

  1. 导入前端素材

    <li><a href="${pageContext.request.contextPath}/jsp/pwdmodify.jsp">密码修改</a></li>
    
  2. 写项目,建议从底层上去写

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0EBL94Pw-1627137531604)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210712203456571.png)]

  3. UserDao接口

        //修改当前用户密码
        public int updatePwd(Connection connection,int id,int password) throws SQLException;
    
  4. UserDao接口实现类

        public int updatePwd(Connection connection, int id, int password) throws SQLException {
            
            PreparedStatement pstm = null;
            int execute = 0;
            if(connection !=null){
                String sql = "update smbms_user set userPassword = ? where id = ?";
                Object params[] = {password,id};
                execute = BaseDao.execute(connection, pstm, sql, params);
                BaseDao.closeResource(null,pstm,null);
            }
    
            return execute;
        }
    
  5. UserService层

        //根据用户ID修改密码
        public boolean updatePwd(int id,int pwd);
    
  6. UserService层实现类

        public boolean updatePwd(int id, int pwd) {
            Connection connection = null;
    
            boolean flag = false;
            //修改密码
            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;
        }
    
  7. 记得实现复用,需要提取出方法,注册Servlet

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String method = req.getParameter("method");
            if(method.equals("savepwd") && method != null){
                this.updatePwd(req,resp);
            }//验证旧密码的
            else if(method.equals("pwdmodify")&&method!=null){
                this.pwdModify(req,resp);
            }
        }
    
    public void updatePwd(HttpServletRequest req, HttpServletResponse resp){
    
            //从Session里面拿ID
            Object o = req.getSession().getAttribute(Constants.USER_SESSION);
    
            String newpassword = req.getParameter("newpassword");
    
            System.out.println("UserServlet: "+newpassword);
    
            boolean flag = false;
    
            if(o != null && newpassword != null){
                UserService userService = new UserServiceImpl();
                flag = userService.updatePwd(((User) o).getId(), newpassword);
                if(flag){
                    req.setAttribute("message","修改密码成功,请退出,使用新密码登录");
                    //密码修改成功,移除当前session
                    req.getSession().removeAttribute(Constants.USER_SESSION);
                }else {
                    req.setAttribute("message","修改密码失败");
                }
            }else {
                req.setAttribute("message","新密码有问题");
            }
            try {
                req.getRequestDispatcher("pwdmodify.jsp").forward(req,resp);
            } catch (ServletException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
  8. 测试

优化密码修改使用Ajax

  1. 阿里巴巴的fastjson

    <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.61</version>
    </dependency>
    
    
  2. 后台代码修改

        //验证旧密码,Session中有用户的密码
        public void pwdModify(HttpServletRequest req, HttpServletResponse resp){
            Object o = req.getSession().getAttribute(Constants.USER_SESSION);
            String oldpassword = req.getParameter("oldpassword");
    
            //万能的Map:结果集
            HashMap<String,String> resultMap = new HashMap<String, String>();
            if(o==null){//Session失效了,Session过期了
                resultMap.put("result","sessionerror");
            }else if(StringUtils.isNullOrEmpty(oldpassword)){//输入的密码为空
                resultMap.put("result","error");
            }else {
                String userPassword = ((User) o).getUserPassword();//session中用户的密码
                if(oldpassword.equals(userPassword)){
                    resultMap.put("result","true");
                }else {
                    resultMap.put("result","false");
                }
            }
    
            try {
                resp.setContentType("application/json");
                PrintWriter writer = resp.getWriter();
                //JSONArray 阿里巴巴的JSON工具类,转换格式
                /*
                resultMap = ["result","sessionerror","result","error"]
                Json格式 = {key:value}
                */
                writer.write(JSONArray.toJSONString(resultMap));
                writer.flush();
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
  3. 测试

用户管理实现

思路:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1dwkdodK-1627137531607)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210713152928711.png)]

  1. 导入分页的工具类

    package com.well.util;
    
    public class PageSupport {
        //当前页码--来自用户输入
        private int currentPageNo = 1;
    
        //总数量(表)
        private int totalCount = 0;
    
        //页码容量
        private int pageSize = 0;
    
        //总页数--totalCount/pageSize(+1)
        private int totalPageCount = 1;
    
        public int getCurrentPageNo(){
            return currentPageNo;
        }
    
        public void setCurrentPageNo(int currentPageNo){
            if (currentPageNo > 0) {
                this.currentPageNo = currentPageNo;
            }
        }
    
        public int getTotalCount() {
            return totalCount;
        }
    
        //oop面向对象三大特性:封装(属性私有,get/set,在set中限定一些不安全的情况),继承,多态
        public void setTotalCount(int totalCount){
            if(totalCount > 0){
                this.totalCount = totalCount;
                //设置总页数
                this.setTotalPageCountRs();
            }
        }
        public int getPageSize(){
            return pageSize;
        }
    
        public void setPageSize(int pageSize){
            if(pageSize > 0){
                this.pageSize = pageSize;
            }
        }
    
        public int getTotalPageCount(){
            return totalPageCount;
        }
    
        public void setTotalPageCount(int totalPageCount){
            this.totalPageCount = totalPageCount;
        }
    
        public void setTotalPageCountRs(){
            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;
            }
        }
    }
    
    
  2. 用户列表页面导入

    userlist.jsp

1、获取用户数量

  1. UserDao

        //查询用户总数
        public int getUserCount(Connection connection,String username,int userRole)throws SQLException;
    
  2. UserDaoImpl

        //根据用户名或者角色 查询用户总数
        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");
                ArrayList<Object> list = new ArrayList<Object>();//存放参数
    
                if(!StringUtils.isNullOrEmpty(username)){
                    sql.append(" and u.userName like ?");
                    list.add("%"+username+"%");  //index:0
                }
                if(userRole>0){
                    sql.append(" and u.userRole like ?");
                    list.add(userRole);//index:1
                }
    
                //怎么把list转换为数组
                Object[] params = list.toArray();
                System.out.println("UserDaoImpl->getUserCount: "+sql.toString());//输出最后完整的sql语句
    
                rs= BaseDao.execute(connection, pstm, rs, sql.toString(), params);
    
                if(rs.next()){
                    count = rs.getInt("count"); //从结果集中获得最终的数量
                }
                BaseDao.closeResource(null,pstm,rs);
            }
            return  count;
        }
    
  3. UserService

        //查询记录数
        public int getUserCount(String username,int userRole);
    
    
  4. UserserviceImpl

        //查询记录数
        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;
        }
    

2、获取用户列表

  1. UserDao

        //获取用户列表
        public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNO, int pageSize) throws SQLException;
    
  2. UserDaoImpl

        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<User>();
            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");
                List<Object> list = new ArrayList<Object>();
                if (! StringUtils.isNullOrEmpty(userName)) {
                    sql.append(" and u.userName like ?");
                    list.add("%"+userName+"%");
                }
                if(userRole > 0){
                    sql.append(" and u.userRole = ?");
                    list.add(userRole);
                }
    
                //在数据库中,分页使用Limit   startIndex,pageSize; 总数
                //当前页(当前页-1)*页面大小
                //0,5   1   0   01234
                //5,5   2   5   56789
                //10,5  3   10
                sql.append(" order by creationDate DESC limit ?,?");
                currentPageNO = (currentPageNO-1)*pageSize;
                list.add(currentPageNO);
                list.add(pageSize);
    
                Object[] params = list.toArray();
                System.out.println("sql -----> " + sql.toString());
                rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
                while (rs.next()){
                    User _usr = new User();
                    _usr.setId(rs.getInt("id"));
                    _usr.setUserCode(rs.getString("userCode"));
                    _usr.setUserName(rs.getString("userName"));
                    _usr.setGender(rs.getInt("gender"));
                    _usr.setBirthday(rs.getDate("birthday"));
                    _usr.setPhone(rs.getString("phone"));
                    _usr.setUserRole(rs.getInt("userRole"));
                    _usr.setUserRoleName(rs.getString("userRoleName"));
                    userList.add(_usr);
                }
                BaseDao.closeResource(null,pstm,rs);
            }
            return userList;
        }
    
  3. UserService

        //根据条件查询用户列表
        public List<User> getUserList(String queryUserName,  int queryUserRole, int currentPageNo, int pageSize);
    
  4. UserserviceImpl

        public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize) {
            Connection connection = null;
            List<User> userList = null;
            System.out.println("queryUserName ----- > " + queryUserName);
            System.out.println("queryUserRole ----- > " + queryUserRole);
            System.out.println("pageSize ----- > " + pageSize);
    
    
            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;
        }
    

3、获取角色操作

为了我们职责统一,可以把角色的操作单独放到一个包中,和POJO类对应

  1. RoleDao

        //获取角色列表
        public List<Role> getRoleList(Connection connection)throws SQLException;
    
  2. RoleDaoImpl

    public class RoleDaoImpl implements RoleDao{
        //获取角色列表
        public List<Role> getRoleList(Connection connection) throws SQLException {
    
            PreparedStatement pstm = null;
            ResultSet rs = null;
            ArrayList<Role> roleList = new ArrayList<Role>();
    
            if (connection != null) {
                String sql = "select * from smbms_role";
                Object[] params = {};
                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;
        }
    }
    
  3. RoleService

    //获取角色列表
    public List<Role> getRoleList();
    
  4. RoleServiceImpl

    public class RoleServlceImpl implements RoleService{
    
        //引入Dao
        private RoleDao roleDao;
        public RoleServlceImpl() {
            roleDao = new RoleDaoImpl();
        }
    
        //查询角色列表
        public List<Role> getRoleList() {
    
            Connection connection = null;
            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;
        }
    }
    

4、用户显示的Servlet

  1. 获取用户前端的数据(查询)

  2. 判断请求是否需要执行,看参数的值判断

  3. 为了实现分页,需要计算出当前页面和总页面,页面大小

  4. 用户列表展示

  5. 返回前端

    else if (method.equals("query")&&method!=null){
                this.query(req,resp);
            }
    
        //重点、难点
        public void query(HttpServletRequest req, HttpServletResponse resp){
    
            //查询用户列表
    
            //从前端获取数据
            String queryUserName = req.getParameter("queryname");
            String temp = req.getParameter("queryUserRole");
            String pageIndex = req.getParameter("pageIndex");
    
            //获取用户列表
            UserServiceImpl userService = new UserServiceImpl();
            List<User> userList =null;
    
            //第一次走这个请求,一定是第一页,页面大小固定的
            int pageSize = 5; //可以把这个写到配置文件中,方便后期修改;
            int currentPageNo = 1;
    
            int queryUserRole = 0;
    
            if (queryUserName == null) {
                queryUserName = "";
            }
            if(temp!=null && !temp.equals("")){
                queryUserRole = Integer.parseInt(temp);  //给查询赋值; 0,1,2,3
            }
            if(pageIndex!=null){
                currentPageNo = Integer.parseInt(pageIndex);
            }
    
            //获取用户的总数(分页:上一页,下一页的情况)
            int totalCount = userService.getUserCount(queryUserName, queryUserRole);
            //总页数支持
            PageSupport pageSupport = new PageSupport();
            pageSupport.setCurrentPageNo(currentPageNo);
            pageSupport.setPageSize(pageSize);
            pageSupport.setTotalCount(totalCount);
    
            int totalPageCount = pageSupport.getTotalPageCount(); //总共有几页
    
            //控制首页和尾页
            //如果页面要小于1了,就显示第一页的东西
            if(totalPageCount < 1){
                currentPageNo = 1;
            }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();
            }
        }
    

No, 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();
       }
   }































































  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值