<>项目简介

smbms超市订单管理系统,主要用于用户管理、订单管理、供应商管理等功能,是学习JavaWeb练习的一个小项目

这个博客只讲了部分功能(用户登录界面,和密码修改界面),以及用户管理的实现。

主要写的后端的实现。

<>使用技术

Maven:管理依赖打包项目
Mysql:存储业务数据
HTML:制作前端登录页面
Servlet:后台服务资源完成相关业务
Tomcat:web项目部署的服务器
Filter:统一会话管理所有登录情况

数据库

<>基本框架搭建

创建dao层(数据持久层),pojo层(简单的Java对象),service(业务层),servlet(服务器层),tools(工具层),filter(过滤层)

dao层主要进行数据库操作,Service(业务层)调用dao层,并将获得的数据传给servlet层,

servlet层负责前后端交互,从前端获取数据,传到后端,并将后端获取的数据返回给前端

service层捕获异常,进行事务处理

事务处理:调用不同dao的多个方法,必须使用同一个connection(connection作为参数传递)事务完成之后,需要在service层进行connection的关闭,在dao层关闭(PreparedStatement和ResultSet对象)

pojo层主要是与数据库对应的一些对象

过滤器层首先要写编码过滤层,防止前后端编码不一致乱码情况

<>项目页面

登录界面

系统首页

密码修改页面

用户管理首页

<>项目搭建

1、搭建一个maven web项目

2、配置tomcat

3、测试项目能否跑起来

4、导入项目中会遇到的jar包

jsp,servlet,mysql驱动,jstl,stand…

5、创建项目包结构

6、编写实体类

ORM映射:表-类映射

7、编写基础公共类

​ 1、数据库配置文件
driver=com.mysql:jdbc.Driver
url=jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf-8
username=root password=123456
3、编写字符编码过滤器

主要是为了前后端连接不出现乱码情况
public class CharacterEncoding implements Filter { @Override public void init(
FilterConfig filterConfig) throws ServletException { } @Override public void
doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException { servletRequest.
setCharacterEncoding("utf-8"); servletResponse.setCharacterEncoding("utf-8");
filterChain.doFilter(servletRequest,servletResponse); } @Override public void
destroy() { } }
8、导入静态资源

<>登录功能实现

1、编写前端页面

* 先在web.xml中设置welcome-file-list
* 前端页面 login.jsp
* loginservlet
* request.getparam()获取前端数据
* 调用业务层
* 匹配成功的话设置session,页面重定向,否则,提示错误(设置页面error属性)
2、设置首页
<!--设置欢迎页面 --> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </
welcome-file-list>
3、编写dao层登录用户登录的接口

按照数据库创建对象user类
public interface UserDao { //得到要登录的用户 public User getLoginUser(Connection
connection,String userCode) throws Exception; }
BaseDao类

数据库操作的方法(连接、查询、更新)
package dao; import java.io.IOException; import java.io.InputStream; import
java.sql.*; import java.util.Properties; 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) { e.printStackTrace(); } driver = properties.
getProperty("driver"); url = properties.getProperty("url"); username =
properties.getProperty("username"); password = properties.getProperty("password"
); } //获取数据库的链接 public static Connection getConnection(){ Connection connection
= null; try { Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager
.getConnection(url, username, password); } catch (Exception e) { e.
printStackTrace(); } return connection; } //编写查询公共方法 public static ResultSet
execute(Connection connection,PreparedStatement preparedStatement,ResultSet
resultSet,String sql,Object[] params) throws SQLException {
//预编译的sql,在后面直接执行就可以了 preparedStatement = connection.prepareStatement(sql); for
(int i = 0; i < params.length; i++) { //setObject,占位符从1开始,但是我们的数组是从0开始!
preparedStatement.setObject(i+1,params[i]); } resultSet = preparedStatement.
executeQuery(); return resultSet; } //编写增删改公共方法 public static int execute(
Connection connection,String sql,Object[] params,PreparedStatement
preparedStatement) throws SQLException { preparedStatement = connection.
prepareStatement(sql); for (int i = 0; i < params.length; i++) {
//setObject,占位符从1开始,但是我们的数组是从0开始! preparedStatement.setObject(i+1,params[i]); }
int updateRows = preparedStatement.executeUpdate(); return updateRows; }
4、编写dao接口的实现类
public class UserDaoImpl implements UserDao{ @Override public User getLoginUser
(Connection connection, String userCode) throws Exception { // TODO
Auto-generated method stub PreparedStatement pstm = null; ResultSet rs = null;
User user= null; if(null != connection){ 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("createdBy"));
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
userPassword); }
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 (Exception e) { e.
printStackTrace(); }finally { BaseDao.closeResource(connection,null,null); }
return user; }
7、编写servlet类
public class LoginServlet extends HttpServlet { //Servlet:控制层,调用业务层代码 @Override
protected void doGet(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);
//这里已经把登录的人给查出来了 System.out.println(userCode); System.out.println(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>
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{ //移除用户的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.doPost(req, resp); } }
注册xml
<servlet> <servlet-name>LogoutServlet</servlet-name> <servlet-class>
servlet.user.LogoutServlet</servlet-class> </servlet> <servlet-mapping> <
servlet-name>LogoutServlet</servlet-name> <url-pattern>/jsp/logout.do</
url-pattern> </servlet-mapping>
<>登录拦截优化

正常情况下退出系统后是登录不了的,但是目前直接输入地址还是能够登录。所以要进行优化

编写一个过滤器并注册
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>filter.SysFilter</filter-class
> </filter> <filter-mapping> <filter-name>Sysfilter</filter-name> <url-pattern>
/jsp/*</url-pattern> </filter-mapping>
<>密码修改

导入前端素材

从底层开始写

UserDao接口实现类
//修改当前用户密码 //增删改都会影响数据库的变化,所以是返回int类型,说明有几行受到了影响 @Override public int updatePwd
(Connection connection, int id, int password) throws Exception { int updateRow=0
; PreparedStatement pstm=null; if (connection!=null){ String sql="UPDATE
`smbms_user` SET `userPassword`=? WHERE `id`=? "; Object[] params={password,id};
BaseDao.execute(connection,sql,params,pstm); } BaseDao.closeResource(null,pstm,
null); return updateRow; }
UserService层

进行事务处理,调用dao层,查找servlet层传来的数据的相关用户,并于servlet层数据进行对比
//修改密码 public boolean updatePwd(int id,int pwd);
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 (Exception e) { e.printStackTrace(
); }finally { BaseDao.closeResource(connection,null,null); } return flag; }
编写修改密码的servlet类

获取数据库用户数据,并设置session属性userlist
public class UserServlet extends HttpServlet { @Override protected void doGet(
HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException{ String method = req.getParameter("method"); if (method.equals(
"savepwd")&&method!=null){ this.modifyPwd(req,resp); }else if (method.equals(
"pwdmodify")&&method!=null){ this.pwdmodify(req,resp); } } @Override protected
void doPost(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException { doGet(req, resp); } //修改密码 public void modifyPwd
(HttpServletRequest req, HttpServletResponse resp){ //获取要修改的密码和id Object
attribute= req.getSession().getAttribute(Constants.USER_SESSION); String
newpassword= req.getParameter("newpassword"); boolean flag = false;
//判断这个session和新密码是否存在 if(attribute!=null && !StringUtils.isNullOrEmpty(
newpassword)){ UserServiceImpl userService = new UserServiceImpl(); flag =
userService.modifyPwd(((User) attribute).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(); } }
注册userservlet
<servlet> <servlet-name>userServlet</servlet-name> <servlet-class>
servlet.user.UserServlet</servlet-class> </servlet> <servlet-mapping> <
servlet-name>userServlet</servlet-name> <url-pattern>/jsp/user.do</url-pattern>
</servlet-mapping>
密码修改成功界面

优化密码修改使用Ajax

AJAX = 异步 JavaScript 和 XML。

AJAX 是一种用于创建快速动态网页的技术。

通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。

有很多使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。

使用jQuery需要导入jQuery,使用Vue导入Vue,两个都用,自己原生态实现

三步曲:

1、编写对应处理的controller,返回消息或者字符串或者json格式的数据

2、编写ajax请求

* url:controller请求
* data:键值对
* success:回调函数
3、给ajax绑定事件,点击。click,失去焦点onblur,键盘弹起keyup

<>用户管理实现

思路:

1、导入分页的工具类

2、用户列表页面导入

<>获取用户数量

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 = ?"); 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; }
<>获取用户列表

1、userdao
//通过条件查询-userList public List<User> getUserList(Connection connection, String
userName, int userRole, int currentPageNo, int pageSize)throws Exception;
2、userdaoImpl
public List<User> getUserList(Connection connection, String userName, int
userRole, int currentPageNo, int pageSize) throws Exception { PreparedStatement
pstm= null; ResultSet rs = null; List<User> userList = new ArrayList<User>(); if
(connection != null){ StringBuffer sql = new StringBuffer(); 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("%"+
userName+"%"); } if(userRole > 0){ sql.append(" and u.userRole = ?"); list.add(
userRole); } 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 _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; }
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(
"currentPageNo ---- > " + currentPageNo); System.out.println("pageSize ---- > "
+ pageSize); try { connection = BaseDao.getConnection(); userList = userDao.
getUserList(connection, queryUserName,queryUserRole,currentPageNo,pageSize); }
catch (Exception e) { e.printStackTrace(); }finally{ BaseDao.closeResource(
connection, null, null); } return userList; }
<>获取角色操作

1、roledao
public interface 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 resultSet = null; ArrayList<Role> roleList = new ArrayList<
Role>(); if (connection!=null){ String sql = "select * from smbms_role"; Object[
] params = {}; resultSet = BaseDao.execute(connection, pstm, resultSet, sql,
params); while (resultSet.next()){ Role _role = new Role(); _role.setId(
resultSet.getInt("id")); _role.setRoleCode(resultSet.getString("roleCode"));
_role.setRoleName(resultSet.getString("roleName")); roleList.add(_role); }
BaseDao.closeResource(null,pstm,resultSet); } return roleList; } }
3、roleservice
//获取角色列表 public List<Role> getRoleList();
4、roleserviceImpl
public class RoleServiceImpl implements RoleService { //引入Dao private RoleDao
roleDao; public RoleServiceImpl() { 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; } }
userservlet中添加query方法

页面没有实现分页,而是全部显示在了一页,加入分页查询
//query方法 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);
//给查询赋值!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
= ((int)(totalCount/pageSize))+1; //控制首页和尾页 //如果页面要小于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("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(); } }
差不多登录和用户管理模块就是这些了

技术
©2019-2020 Toolsou All rights reserved,
vue项目中使用本地静态JS数据文件利用克鲁斯卡尔算法求最小生成树C++ 移动构造函数和拷贝构造函数华为鸿蒙 HarmonyOS 2 正式发布VS添加动态链接库的两种方法python_樱花树Jmeter配置元件之HTTP授权管理器与 HTTP缓存管理器-19vue+element-ui里面table组件多选框实现批量操作RISC-V指令集架构特点及其总结js实现上下文菜单