smbms(超市订单管理系统)

项目实战:smbms(超市订单管理系统)

一、项目搭建准备工作

  1. 创建一个maven项目,配置好tomcat.
  2. 导入项目中需要的一些jar包(配置pom.xml文件)

pom.xml文件

<?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>com.tang</groupId>
    <artifactId>smbms</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
<!--        单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>
<!--        servlet依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
<!--        jsp依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
<!--        MySQL驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>
        <!--    jstl表达式依赖-->
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>
        <!--    standard标签库-->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
    </dependencies>

</project>
  1. 创建项目包结构

pojo/entity: 实体层,存放实体类(与数据库中的表一一对应)

dao: 数据访问层(调用实体层代码),封装对数据库的访问(即增删改查),不涉及业务逻辑

service: 业务逻辑层(调用数据访问层代码),处理逻辑上的业务,二不去考虑其具体的实现

servlet: 控制层(调用业务层代码),主要用于和浏览器交互,交互式地浏览和修改数据

util: Util层,是一个多功能、基于工具的包(存放工具类)

filter: 用于存放过滤器

  1. 编写实体类

ORM映射(表–>类映射)

idea中又工具可以直接快捷生成表对应的实体类,只需要稍作修改。

User.java

package com.tang.pojo;

/*
    用户表
 */

import java.util.Date;

public class User {
    
    

  private Integer id;  //id
  private String userCode;  //用户编码
  private String userName;  //用户名
  private String userPassword;  //用户密码
  private Integer gender;  //性别
  private Date birthday;  //生日
  private String phone;  //电话
  private String address;  //地址
  private Integer userRole;  //用户角色(id)
  private Integer createdBy;  //创建者
  private Date creationDate;  //创建时间
  private Integer modifyBy;  //更新者
  private Date modifyDate;  //更新时间


  private Integer age;  //年龄
  private String userRoleName;  //用户角色名称

  public Integer getAge() {
    
    
    Date date = new Date();
    age = date.getYear() - birthday.getYear();
    return age;
  }

  public String getUserRoleName() {
    
    
    return userRoleName;
  }

  public void setUserRoleName(String id) {
    
    
    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;
  }

}

Role.java

Bill.java

Provider.java

  1. 编写基础公共类
  • 数据库配置文件

db.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/smbms?characterEncoding=utf-8&&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
username=root
password=root

BaseDao.java

/*
    操作数据库的公共类
 */
public class BaseDao {
    
    
    private static String driver;
    private static String url;
    private static String username;
    private static String password;

    // 静态代码块,类加载的时候就初始化
    static {
    
    
        Properties properties = new Properties();
        // 通过类加载器读取对应的资源
        InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");

        try {
    
    
            properties.load(is);
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }

        driver = properties.getProperty("driver");
        url = properties.getProperty("url");
        username = properties.getProperty("username");
        password = properties.getProperty("password");
    }

    /**
     * 获取数据库的连接
     * @return connection
     */
    public static Connection getConnection() {
    
    
        Connection connection = null;
        try {
    
    
            //加载驱动
            Class.forName(driver);
            //连接数据库
            connection = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
    
    
            throw new RuntimeException(e);
        }
        return connection;
    }

    /**
     * 编写查询公共方法
     * @param connection
     * @param sql
     * @param param
     * @param preparedStatement
     * @param resultSet
     * @return resultSet
     * @throws SQLException
     */
    public static ResultSet execute(Connection connection, PreparedStatement preparedStatement,
                                    ResultSet resultSet, String sql, Object[] param) throws SQLException {
    
    
        //preparedStatement: 用户向数据库 执行sql语句 的预编译对象(CRUD)
        preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < param.length; i++) {
    
    
            //setObject的占位符从1开始,但我们的数组是从0开始的
            preparedStatement.setObject(i+1, param[i]);
        }
        resultSet = preparedStatement.executeQuery();
        return resultSet;
    }

    /**
     * 编写增删改公共方法
     * @param connection
     * @param sql
     * @param param
     * @param preparedStatement
     * @return
     * @throws SQLException
     */
    public static int execute(Connection connection, PreparedStatement preparedStatement,
                              String sql, Object[] param) throws SQLException {
    
    

        //preparedStatement: 用户向数据库 执行sql语句 的预编译对象(CRUD)
        preparedStatement = connection.prepareStatement(sql);
        for (int i = 0; i < param.length; i++) {
    
    
            //setObject的占位符从1开始,但我们的数组是从0开始的
            preparedStatement.setObject(i+1, param[i]);
        }
        int updateRow = preparedStatement.executeUpdate();
        return updateRow;
    }

    /**
     * 释放资源
     * @param connection
     * @param preparedStatement
     * @param resultSet
     * @return flag
     */
    public static Boolean closeResouces(Connection connection,
                                        PreparedStatement preparedStatement, ResultSet resultSet) {
    
    
        Boolean flag = true;

        if (connection != null) {
    
    
            try {
    
    
                connection.close();
                // GC回收
                connection = null;
            } catch (SQLException e) {
    
    
                flag = false;
                throw new RuntimeException(e);
            }
        }

        if (preparedStatement != null) {
    
    
            try {
    
    
                preparedStatement.close();
                // GC回收
                preparedStatement = null;
            } catch (SQLException e) {
    
    
                flag = false;
                throw new RuntimeException(e);
            }
        }

        if (resultSet != null) {
    
    
            try {
    
    
                resultSet.close();
                // GC回收
                resultSet = null;
            } catch (SQLException e) {
    
    
                flag = false;
                throw new RuntimeException(e);
            }
        }

        return flag;
    }

}
  • 编写过滤器解决字符编码问题

CharacterEnCodingFilter.java

package com.tang.filter;

import javax.servlet.*;
import java.io.IOException;

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

    }

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    
    
        // Chain: 链
        /*
            1.过滤器中的所有代码,在过滤特定请求的时候都会执行
            2.必须要让过滤器继续通行
                filterChain.doFilter(servletRequest, servletResponse);
         */
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");
        servletResponse.setContentType("text/html; charset=UTF-8");

        filterChain.doFilter(servletRequest, servletResponse);  // 让我们的请求继续走,如果不写,程序到这里就会被拦截停止
    }

    public void destroy() {
    
    

    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    

<!--    编写字符编码过滤器-->
    <filter>
        <filter-name>CharacterEnCodingFilter</filter-name>
        <filter-class>com.tang.filter.CharacterEnCodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEnCodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>
  1. 导入静态资源,将静态资源方到web目录下即可

(具体资源可在git此项目中获取https://gitee.com/tang-huiyang/java-web-learning)

到这,准备工作也就完毕了!

二、登录功能实现

  1. 编写前端页面

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
    <title>系统登录 - 超市订单管理系统</title>
    <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath}/css/style.css">
    <script type="text/javascript">
       /* if (top.location != self.location) {
            top.location = self.location;
        }*/
    </script>
</head>
<body class="login_bg">
    <section class="loginBox">
        
        <header class="loginHeader">
            <h1>超市订单管理系统</h1>
        </header>
        
        <section class="loginCont">
            <form class="loginForm" action="${pageContext.request.contextPath}/login.do"
                  name="cationForm" id="cationForm" method="post">
                <div class="info">
                    ${error}
                </div>
                <div class="inputbox">
                    <label>用户名:</label>
                    <input type="text" class="input-text" id="userCode" name="userCode" placeholder="请输入用户名" required>
                </div>
                
                <div class="inputbox">
                    <label>密码:</label>
                    <input type="password" id="userPassword" name="userPassword" placeholder="请输入密码" required>
                </div>
                
                <div class="subBtn">
                    <input type="submit" value="登录">
                    <input type="reset" value="重置">
                </div>
            </form>
        </section>
        
    </section>
</body>
</html>
  1. 设置首页

在web.xml文件中加入以下代码

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

UserDao.java

package com.tang.dao.user;

import com.tang.pojo.User;

import java.sql.Connection;
import java.sql.SQLException;

public interface UserDao {
    
    

    // 得到要登录的用户
    public User getLoginUser(Connection connection, String userCode) throws SQLException;

}
  1. 编写dao接口的实现类

UserDaoImol.java

package com.tang.dao.user;

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

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

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[] param = {
    
    userCode};

            // 查询要登录用户在数据库表中的全部信息
            rs = BaseDao.execute(connection, pstm, rs, sql, param);
            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("createdBy"));
                user.setCreationDate(rs.getTimestamp("creationDate"));
                user.setModifyBy(rs.getInt("modifyBy"));
                user.setModifyDate(rs.getTimestamp("modifyDate"));
            }
            // 释放资源
            BaseDao.closeResouces(null, pstm, rs);
        }
        return user;
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7R36ttq3-1691474856106)(./smbms(超市订单管理系统).assets/image-20230729151355000.png)]

  1. 编写业务层用户登录接口

UserService.java

package com.tang.service.user;

import com.tang.pojo.User;

public interface UserService {

    // 用户登录
    public User login(String userCode, String password);

}
  1. 编写业务层实现类

UserServiceImpl.java

package com.tang.service.user;

import com.tang.dao.BaseDao;
import com.tang.dao.user.UserDao;
import com.tang.dao.user.UserDaoImpl;
import com.tang.pojo.User;
import org.junit.Test;

import java.sql.Connection;
import java.sql.SQLException;

public class UserServiceImpl implements UserService{
    
    

    // 业务层都会调用dao层,所以我们要引入dao层
    private UserDao userDao;
    public UserServiceImpl() {
    
      //无参构造方法,此时当UserServiceImpl被实例化,就可以获取对象userDao
        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) {
    
    
            throw new RuntimeException(e);
        } finally {
    
    
            BaseDao.closeResouces(connection,null,null);
        }

        return user;
    }


    @Test
    public void test() {
    
    
        UserServiceImpl userService = new UserServiceImpl();
        User admin = userService.login("admin", "123456789"); //这里的密码不一定是正确的
        System.out.println(admin.getUserPassword());  //1234567
    }

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cfj0Iony-1691474856107)(./smbms(超市订单管理系统).assets/image-20230729165505427.png)]

  1. 编写Servlst

Constants.java

package com.tang.util;

/*
     用于存放常量
 */

public class Constants {
    
    
    public final static String USER_SESSION = "userSession";
}

LoginServlet.java

package com.tang.servlet.user;

import com.tang.pojo.User;
import com.tang.service.user.UserService;
import com.tang.service.user.UserServiceImpl;
import com.tang.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 {
    
    
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        System.out.println("LoginServlet-start...");

        // 获取用户输入的用户名和密码
        String userCode = req.getParameter("userCode");
        String userPassword = req.getParameter("userPassword");

        //调用业务层,和数据控中的密码进行比对
        UserService userService = new UserServiceImpl();
        User user = userService.login(userCode, userPassword);   //这里就已经把登录的人给查出来了

        // 查有此人,且用户输入密码正确,可以登录
        if (user != null && user.getUserPassword().equals(userPassword) {
    
      
            // 将用户的信息放到Session中
            req.getSession().setAttribute(Constants.USER_SESSION, user);
            // 跳转到主页(重定向)
            resp.sendRedirect("/jsp/frame.jsp");
        } else {
    
      // 用户名不存在或密码错误,无法登录
            // 转发会登录页面,顺便提示它,用户名或密码错误
            req.setAttribute("error", "用户名或密码错误!");
            req.getRequestDispatcher("/login.jsp").forward(req, resp);
        }
    }
}
  1. 注册Servlet
<!--    Servlet-->
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.tang.servlet.user.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login.do</url-pattern>
    </servlet-mapping>
  1. 设置默认Session过期时间

在web.xml文件中添加

<!--  设置默认session过期时间-->
  <session-config>
    <session-timeout>30</session-timeout>
  </session-config>

三、登录功能优化

  • 注销功能

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

LogoutServlet.java

package com.tang.servlet.user;

import com.tang.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 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 {
    
    
        super.doGet(req, resp);
    }
}

注册xml

<servlet>
  <servlet-name>LogoutServlet</servlet-name>
  <servlet-class>com.tang.servlet.user.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>LogoutServlet</servlet-name>
  <url-pattern>/jsp/logout.do</url-pattern>
</servlet-mapping>
  • 登录拦截优化

编写登录过滤器

SysFilter.java

package com.tang.filter;

import com.tang.pojo.User;
import com.tang.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 servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;

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

        if (user == null) {  // 已经被移除或注销了,或者未登录
            resp.sendRedirect(req.getContextPath() + "/error.jsp");
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }

    }

    public void destroy() {

    }
}

注册xml

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

四、密码修改

写项目建议从底层向上写

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WQJPbyqM-1691474856108)(./smbms(超市订单管理系统).assets/image-20230730224848085.png)]

  1. UserDao接口(在数据库中修改密码,返回改变行数)

UserDao.java中加入代码

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

UserDaoImpl.java加入代码

public int updatePwd(Connection connection, int id, String password) throws SQLException {
    
    
    int execute = 0;

    PreparedStatement pstm = null;
    String sql = "update smbms_user set userPassword = ? where id = ?";
    Object[] param = {
    
    password, id};

    if (connection != null) {
    
    
        execute = BaseDao.execute(connection, pstm, sql, param);
        BaseDao.closeResouces(null, pstm, null);
    }

    return execute;
}
  1. UserService接口

获取dao层返回的改变层数,进行判断。大于0,修改成功,返回true,小于0反之)

UserService.java中加入代码

// 根据用户id修改密码
public boolean updatePwd(int id, String password);
  1. UserService接口实现类

UserDaoImpl.java加入代码

public boolean updatePwd(int id, String password) {
    
    
    boolean flag = false;
    Connection connection = null;

    try {
    
    
        connection = BaseDao.getConnection();
        if (userDao.updatePwd(connection, id, password) > 0){
    
      // 修改成功
            flag = true;
        }
    } catch (SQLException e) {
    
    
        throw new RuntimeException(e);
    } finally {
    
    
        BaseDao.closeResouces(connection, null, null);
    }

    return flag;
}
  1. 编写控制层代码

获取service返回的结果,结合前端做出响应

为了实现服用,我们把具体逻辑封装成方法

UserServlet.java

package com.tang.servlet.user;

import com.mysql.cj.util.StringUtils;
import com.tang.pojo.User;
import com.tang.service.user.UserServiceImpl;
import com.tang.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 UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    // 实现Servlet复用
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        if (method.equals("updatePwd")) {
            this.updatePwd(req, resp);
        }
    }

    /**
     * 修改密码
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    public void updatePwd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 从Session里面拿到id
        User user = (User) req.getSession().getAttribute(Constants.USER_SESSION);
        String newpassword = req.getParameter("newpassword");

        boolean flag = false;
        // StringUtils.isNullOrEmpty(newpassword):  判断字符串是否为空,不为空返回 false
        if (user != null && !StringUtils.isNullOrEmpty(newpassword)) {
            UserServiceImpl userService = new UserServiceImpl();
            flag = userService.updatePwd(user.getId(), newpassword);
            if (flag) {
                req.setAttribute("message", "修改密码成功,使用新密码重新登录");
                // 密码修改成功,移除当前Session
                req.getSession().removeAttribute(Constants.USER_SESSION);
            } else {
                req.setAttribute("message", "修改密码失败");
            }
        } else {
            req.setAttribute("message", "新密码有问题");
        }

        req.getRequestDispatcher("pwdmodify.jsp").forward(req, resp);
    }
}

注册xml

<servlet>
  <servlet-name>UserServlet</servlet-name>
  <servlet-class>com.tang.servlet.user.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>UserServlet</servlet-name>
  <url-pattern>/jsp/user.do</url-pattern>
</servlet-mapping>

五、优化密码修改

结合Ajax判断用户修改密码时输入的旧密码是否正确

前端代码

pwdmodify.js

var oldpassword = null;
var newpassword = null;
var rnewpassword = null;
var saveBtn = null;

$(function(){
    
    
   oldpassword = $("#oldpassword");
   newpassword = $("#newpassword");
   rnewpassword = $("#rnewpassword");
   saveBtn = $("#save");
   
   oldpassword.next().html("*");
   newpassword.next().html("*");
   rnewpassword.next().html("*");
   
   oldpassword.on("blur",function(){
    
    
      $.ajax({
    
    
         type:"POST",
         url:path+"/jsp/user.do",
         data:{
    
    method:"pwdmodify",oldpassword:oldpassword.val()},
         dataType:"json",
         success:function(data){
    
    
            if(data.result == "true"){
    
    //旧密码正确
               validateTip(oldpassword.next(),{
    
    "color":"green"},imgYes,true);
            }else if(data.result == "false"){
    
    //旧密码输入不正确
               validateTip(oldpassword.next(),{
    
    "color":"red"},imgNo + " 原密码输入不正确",false);
            }else if(data.result == "sessionerror"){
    
    //当前用户session过期,请重新登录
               validateTip(oldpassword.next(),{
    
    "color":"red"},imgNo + " 当前用户session过期,请重新登录",false);
            }else if(data.result == "error"){
    
    //旧密码输入为空
               validateTip(oldpassword.next(),{
    
    "color":"red"},imgNo + " 请输入旧密码",false);
            }
         },
         error:function(data){
    
    
            //请求出错
            validateTip(oldpassword.next(),{
    
    "color":"red"},imgNo + " 请求错误",false);
         }
      });
      
      
   }).on("focus",function(){
    
    
      validateTip(oldpassword.next(),{
    
    "color":"#666666"},"* 请输入原密码",false);
   });
   
   newpassword.on("focus",function(){
    
    
      validateTip(newpassword.next(),{
    
    "color":"#666666"},"* 密码长度必须是大于6小于20",false);
   }).on("blur",function(){
    
    
      if(newpassword.val() != null && newpassword.val().length > 5
            && newpassword.val().length < 20 ){
    
    
         validateTip(newpassword.next(),{
    
    "color":"green"},imgYes,true);
      }else{
    
    
         validateTip(newpassword.next(),{
    
    "color":"red"},imgNo + " 密码输入不符合规范,请重新输入",false);
      }
   });
   
   
   rnewpassword.on("focus",function(){
    
    
      validateTip(rnewpassword.next(),{
    
    "color":"#666666"},"* 请输入与上面一致的密码",false);
   }).on("blur",function(){
    
    
      if(rnewpassword.val() != null && rnewpassword.val().length > 5
            && rnewpassword.val().length < 20 && newpassword.val() == rnewpassword.val()){
    
    
         validateTip(rnewpassword.next(),{
    
    "color":"green"},imgYes,true);
      }else{
    
    
         validateTip(rnewpassword.next(),{
    
    "color":"red"},imgNo + " 两次密码输入不一致,请重新输入",false);
      }
   });
   
   
   saveBtn.on("click",function(){
    
    
      oldpassword.blur();
      newpassword.blur();
      rnewpassword.blur();
      if(oldpassword.attr("validateStatus") == "true"
         && newpassword.attr("validateStatus") == "true"
         && rnewpassword.attr("validateStatus") == "true"){
    
    
         if(confirm("确定要修改密码?")){
    
    
            $("#userForm").submit();
         }
      }
      
   });
});

后端代码

  1. 导入依赖,使用阿里巴巴的fastjson转换为JSON数据
<!--    json操作依赖-->
    <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>2.0.32</version>
    </dependency>
  1. UserServlet.java中加入方法
/**
 * 验证旧密码是否正确
 * @param req
 * @param resp
 */
public void pwdModify(HttpServletRequest req, HttpServletResponse resp) {
    
    
    // 在Session里面拿到用户信息,和用户输入的旧密码
    User user = (User) req.getSession().getAttribute(Constants.USER_SESSION);
    String oldpassword = req.getParameter("oldpassword");

    //Map结果集
    Map<String, String> resultMap = new HashMap<String, String>();

    if (user == null) {
    
      // session失效或过期了
        resultMap.put("result", "sessionerror");
    } else if (StringUtils.isNullOrEmpty(oldpassword)) {
    
      // 输入密码为空
        resultMap.put("result", "error");
    } else {
    
    
        // 获取Session中用户的密码
        String userPassword = user.getUserPassword();
        if (userPassword.equals(oldpassword)) {
    
      // 用户输入密码正确
            resultMap.put("result", "true");
        } else {
    
      // 用户输入密码错误
            resultMap.put("result", "false");
        }
    }


    try {
    
    
        resp.setContentType("application/json");
        PrintWriter writer = resp.getWriter();
        // JSONArray:阿里巴巴的JSON工具类,转换格式
        writer.write(JSONArray.toJSONString(resultMap));  //将Map结合转换为JSON的数据
        writer.flush();
        writer.close();
    } catch (IOException e) {
    
    
        throw new RuntimeException(e);
    }
}
  1. 在doGet方法中加入以下代码

(这里本应该在doPost方法中加入的,因为我在前端pwdmodify.jsajax代码中设置的方法类型是post,但不知道怎么回事,走的是get请求,页面报错405)

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        String method = req.getParameter("method");
        if (method.equals("pwdmodify")){
    
    
            this.pwdModify(req, resp);
        }
    }

六、用户管理实现

  1. 导入用户分页工具类

PageSupport.java

package com.tang.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;
   }

   public void setTotalCount(int totalCount) {
    
    
      if(totalCount > 0){
    
    
         this.totalCount = totalCount;
         //设置总页数
         this.setTotalPageCountByRs();
      }
   }
   public int getPageSize() {
    
    
      return pageSize;
   }

   public void setPageSize(int pageSize) {
    
    
      if(pageSize > 0){
    
    
         this.pageSize = pageSize;
      }
   }

    public int getTotalPageCount() {
    
    
        int totalPageCount = totalCount / pageSize;
        if (totalCount % pageSize != 0) {
    
    
            totalPageCount++;
        }
        return totalPageCount;
    }

   public void setTotalPageCount(int totalPageCount) {
    
    
      this.totalPageCount = totalPageCount;
   }
   
   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;
      }
   }
   
}
  1. 导入用户列表页面

userlist.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
   pageEncoding="UTF-8"%>
<%@include file="/jsp/common/head.jsp"%>
        <div class="right">
            <div class="location">
                <strong>你现在所在的位置是:</strong>
                <span>用户管理页面</span>
            </div>
            <div class="search">
                  <form method="get" action="${pageContext.request.contextPath }/jsp/user.do">
               <input name="method" value="query" class="input-text" type="hidden">
                <span>用户名:</span>
                <input name="queryname" class="input-text"    type="text" value="${queryUserName }">
                
                <span>用户角色:</span>
                <select name="queryUserRole">
                  <c:if test="${roleList != null }">
                     <option value="0">--请选择--</option>
                     <c:forEach var="role" items="${roleList}">
                            <option <c:if test="${role.id == queryUserRole }">selected="selected"</c:if>
                            value="${role.id}">${role.roleName}</option>
                     </c:forEach>
                  </c:if>
                 </select>
                
                <input type="hidden" name="pageIndex" value="1"/>
                <input    value="查 询" type="submit" id="searchbutton">
                <a href="${pageContext.request.contextPath}/jsp/useradd.jsp" >添加用户</a>
            </form>
            </div>
            <!--用户-->
            <table class="providerTable" cellpadding="0" cellspacing="0">
                <tr class="firstTr">
                    <th width="10%">用户编码</th>
                    <th width="20%">用户名称</th>
                    <th width="10%">性别</th>
                    <th width="10%">年龄</th>
                    <th width="10%">电话</th>
                    <th width="10%">用户角色</th>
                    <th width="30%">操作</th>
                </tr>
                   <c:forEach var="user" items="${userList }" varStatus="status">
               <tr>
                  <td>
                  <span>${user.userCode }</span>
                  </td>
                  <td>
                  <span>${user.userName }</span>
                  </td>
                  <td>
                     <span>
                        <c:if test="${user.gender==1}">男</c:if>
                        <c:if test="${user.gender==2}">女</c:if>
                     </span>
                  </td>
                  <td>
                  <span>${user.age}</span>
                  </td>
                  <td>
                  <span>${user.phone}</span>
                  </td>
                  <td>
                     <span>${user.userRoleName}</span>
                  </td>
                  <td>
                  <span><a class="viewUser" href="javascript:;" userid=${user.id } username=${user.userName }><img src="${pageContext.request.contextPath }/images/read.png" alt="查看" title="查看"/></a></span>
                  <span><a class="modifyUser" href="javascript:;" userid=${user.id } username=${user.userName }><img src="${pageContext.request.contextPath }/images/xiugai.png" alt="修改" title="修改"/></a></span>
                  <span><a class="deleteUser" href="javascript:;" userid=${user.id } username=${user.userName }><img src="${pageContext.request.contextPath }/images/schu.png" alt="删除" title="删除"/></a></span>
                  </td>
               </tr>
            </c:forEach>
         </table>
         <input type="hidden" id="totalPageCount" value="${totalPageCount}"/>
         <c:import url="rollpage.jsp">
              <c:param name="totalCount" value="${totalCount}"/>
              <c:param name="currentPageNo" value="${currentPageNo}"/>
              <c:param name="totalPageCount" value="${totalPageCount}"/>
           </c:import>
        </div>
    </section>

<!--点击删除按钮后弹出的页面-->
<div class="zhezhao"></div>
<div class="remove" id="removeUse">
    <div class="removerChid">
        <h2>提示</h2>
        <div class="removeMain">
            <p>你确定要删除该用户吗?</p>
            <a href="#" id="yes">确定</a>
            <a href="#" id="no">取消</a>
        </div>
    </div>
</div>

<%@include file="/jsp/common/foot.jsp" %>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/userlist.js"></script>

下方分页条

rollpage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!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>Insert title here</title>
<script type="text/javascript">
   
</script>
</head>
<body>
      <div class="page-bar">
         <ul class="page-num-ul clearfix">
            <li>共${param.totalCount }条记录&nbsp;&nbsp; ${param.currentPageNo }/${param.totalPageCount }页</li>
            <c:if test="${param.currentPageNo > 1}">
               <a href="javascript:page_nav(document.forms[0],1);">首页</a>
               <a href="javascript:page_nav(document.forms[0],${param.currentPageNo-1});">上一页</a>
            </c:if>
            <c:if test="${param.currentPageNo < param.totalPageCount }">
               <a href="javascript:page_nav(document.forms[0],${param.currentPageNo+1 });">下一页</a>
               <a href="javascript:page_nav(document.forms[0],${param.totalPageCount });">最后一页</a>
            </c:if>
            &nbsp;&nbsp;
         </ul>
       <span class="page-go-form"><label>跳转至</label>
        <input type="text" name="inputPage" id="inputPage" class="page-key" />页
        <button type="button" class="page-btn" onClick='jump_to(document.forms[0],document.getElementById("inputPage").value)'>GO</button>
      </span>
      </div> 
</body>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/rollpage.js"></script>
</html>

1、获取用户数量

1.1 UserDao

// 根据用户名或者角色查询用户总数
public int getUserCount(Connection connection, String userName, int userRole) throws SQLException;

1.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) {
    
    
        StringBuilder sql = new StringBuilder();
        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)) {
    
      // userName不为空
            sql.append(" and u.userName like ?");
            list.add("%" + userName + "%");  // index: 0
        }
        if (userRole > 0) {
    
    
            sql.append(" and u.userRole = ?");
            list.add(userRole);  //index: 1
        }

        // 将list转换为数组
        Object[] params = list.toArray();

        System.out.println("UserDaoImpl->getUserCount:" + sql.toString());  //输出完整的sql语句

        //执行sql语句
        rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
        if (rs.next()) {
    
    
            count = rs.getInt("count");  //从结果集中获取最终的数量
        }

    }

    return count;
}

1.3 UserService

// 查询记录数
public int getUserCount(String userName, int userRole);

1.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) {
    
    
        throw new RuntimeException(e);
    } finally {
    
    
        BaseDao.closeResouces(connection, null, null);
    }

    return count;
}

// 测试代码
@Test
public void test2() {
    
    
    UserServiceImpl userService = new UserServiceImpl();
    userService.getUserCount(null,1);
}

2、获取用户列表

2.1 UserDao

// 根据条件查询--userList
public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize)
        throws SQLException;

2.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) {
    
    
        StringBuilder sql = new StringBuilder();
        sql.append("select u.*,r.roleName as userRoleName 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("%" + userRole + "%");
        }
        if (userRole > 0) {
    
    
            sql.append(" and u.userRole = ?");
            list.add(userRole);
        }
        sql.append(" order by creationDate DESC limit ?, ?");
        list.add((currentPageNo - 1) * pageSize);
        list.add(pageSize);

        Object[] params = list.toArray();
        System.out.println("UserDaoImpl->getUserList:" + sql.toString());
        // 执行sql
        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.closeResouces(null, pstm, rs);
    }

    return userList;
}

2.3 UserService

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

2.4 UserServiceImpl

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) {
    
    
        throw new RuntimeException(e);
    } finally {
    
    
        BaseDao.closeResouces(connection, null, null);
    }

    return userList;
}

3、获取角色操作

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

3.1 role/RoleDao

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

3.2 role/RoleDaoImpl

public class RoleDaoImpl implements RoleDao{
    
    

    public List<Role> getRoleList(Connection connection) throws SQLException {
    
    
        PreparedStatement pstm = null;
        ResultSet rs = null;
        List<Role> roleList = new ArrayList<Role>();

        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.closeResouces(null, pstm, rs);
        }

        return roleList;
    }

}

3.3 role/RoleService

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

3.4 role/RoleServiceImpl

public class RoleServiceImpl implements RoleService{
    
    

    // 引入dao
    private RoleDao roleDao;
    public RoleServiceImpl (RoleDao roleDao) {
    
    
        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) {
    
    
            throw new RuntimeException(e);
        } finally {
    
    
            BaseDao.closeResouces(connection, null, null);
        }

        return roleList;
    }
}

// 测试
  @Test
    public void test() {
    
    
        RoleServiceImpl roleService = new RoleServiceImpl();
        List<Role> roleList = roleService.getRoleList();
        for (Role role : roleList) {
    
    
            System.out.println(role.getRoleName());
        }
    }

4、servlet控制层代码

UserServlet.java

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
    String method = req.getParameter("method");
    if (method.equals("pwdmodify")) {
    
    
        this.pwdModify(req, resp);
    } else if (method.equals("query")) {
    
    
        this.query(req, resp);
    }
}

// 实现Servlet复用
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
    String method = req.getParameter("method");
    if (method.equals("savepwd")) {
    
    
        this.updatePwd(req, resp);
    }
}
/**
 * 获取用户列表
 *
 * @param req
 * @param resp
 */
public void query(HttpServletRequest req, HttpServletResponse resp) {
    
    

    // 从前端获取数据
    String queryUserName = req.getParameter("queryname");
    String temp = req.getParameter("queryUserRole");
    String pageIndex = req.getParameter("pageIndex");
    int queryUserRole = 0;

    //获取用户列表
    UserServiceImpl userService = new UserServiceImpl();
    List<User> userList = null;

    // 第一次走这个请求一定是第一页,页面大小事固定的
    int pageSize = 5;
    int currentPageNo = 1;

    if (queryUserName == null) {
    
    
        queryUserName = "";
    }
    if (temp != null && !temp.equals("")) {
    
    
        queryUserRole = Integer.parseInt(temp);
    }
    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 (currentPageNo < 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("totalPageCount", totalPageCount);
    req.setAttribute("totalCount", totalCount);
    req.setAttribute("currtentPageNo", currentPageNo);
    req.setAttribute("queryUserName", queryUserName);
    req.setAttribute("queryUserRole", queryUserRole);
    System.out.println(currentPageNo);

    // 返回前端
    try {
    
    
        req.getRequestDispatcher("userlist.jsp").forward(req, resp);
    } catch (ServletException e) {
    
    
        throw new RuntimeException(e);
    } catch (IOException e) {
    
    
        throw new RuntimeException(e);
    }
}

七、商品管理和供应商管理

该模块和用户管理模块大同小异

八、完整项目前往该地址查看

https://gitee.com/tang-huiyang/java-web-learning

猜你喜欢

转载自blog.csdn.net/qq_62761962/article/details/132165734