超市订单管理系统 1、整体架构
2、项目搭建准备
按webapp步骤搭建web项目(目录结构)—->
配置Tomcat—–>
导入项目依赖jar(基本依赖)—->
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <dependencies > <dependency > <groupId > jakarta.servlet</groupId > <artifactId > jakarta.servlet-api</artifactId > <version > 5.0.0</version > </dependency > <dependency > <groupId > jakarta.servlet.jsp</groupId > <artifactId > jakarta.servlet.jsp-api</artifactId > <version > 3.0.0</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.21</version > </dependency > </dependencies >
创建项目包结构
编写实体类
ORM(表<—->类)映射,可以在IDEA中根据数据库表自动生成(需要少量修改)。
编写基础公共类
1 2 3 4 driver =com.mysql.jdbc.Driver url =jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf-8 user =root password =123456
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 package com.pans.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 () throws ClassNotFoundException, SQLException { Class.forName(driver); Connection connection = DriverManager.getConnection(url, username, password); return connection; } public static ResultSet excute (Connection connection,String sql,Object[] params,ResultSet resultSet, PreparedStatement preparedStatement) throws SQLException { preparedStatement = connection.prepareStatement(sql); for (int i = 0 ; i < params.length; i++) { preparedStatement.setObject(i+1 ,params[i]); } resultSet = preparedStatement.executeQuery(); return resultSet; } public static int excute (Connection connection,String sql,Object[] params, PreparedStatement preparedStatement) throws SQLException { preparedStatement = connection.prepareStatement(sql); for (int i = 0 ; i < params.length; i++) { preparedStatement.setObject(i+1 ,params[i]); } int updateRows= preparedStatement.executeUpdate(); return updateRows; } public static boolean closeResource (Connection connection,PreparedStatement preparedStatement,ResultSet resultSet) { boolean flag = true ; if (resultSet != null ){ try { resultSet.close(); resultSet = null ; }catch (Exception e){ flag = false ; } } if (preparedStatement != null ){ try { preparedStatement.close(); preparedStatement = null ; }catch (Exception e){ flag = false ; } } if (connection != null ){ try { connection.close(); connection = null ; }catch (Exception e){ flag = false ; } } return flag; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package com.pans.filter;import javax.servlet.*;import java.io.IOException;public class CharacterEncodingFilter implements Filter { @Override public void init (FilterConfig filterConfig) throws ServletException { Filter.super .init(filterConfig); } @Override public void destroy () { Filter.super .destroy(); } @Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { request.setCharacterEncoding("utf-8" ); response.setCharacterEncoding("utf-8" ); chain.doFilter(request,response); } }
导入静态资源
3、登录功能实现
1. 编写前端页面login.jsp 2. 设置首页为login.jsp 1 2 3 <welcome-file-list > <welcome-file > login.jsp</welcome-file > </welcome-file-list >
3. 编写Dao层登录用户登陆的接口 1 2 3 4 5 6 7 8 9 10 11 package com.pans.dao.user;import com.pans.pojo.User;import java.sql.Connection;public interface UserDao { public User getLoginUser (Connection connection, String userCode) throws Exception; }
4. 编写Dao接口的实现类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package com.pans.dao.user;import com.pans.dao.BaseDao;import com.pans.pojo.User;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;public class UserDaoImpl implements UserDao { @Override public User getLoginUser (Connection connection, String userCode) throws Exception { 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. 编写业务层接口及其实现类 ==此时在做测试的遇到的bug:==
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package com.pans.service.user;import com.pans.dao.BaseDao;import com.pans.dao.user.UserDao;import com.pans.dao.user.UserDaoImpl;import com.pans.pojo.User;import org.junit.Test;import java.sql.Connection;import java.sql.SQLException;public class UserServiceImpl implements UserService { private UserDao userDao; public UserServiceImpl () { userDao = new UserDaoImpl (); } @Override public User login (String userCode, String password) { Connection connection = null ; User user = new User (); try { connection = BaseDao.getConnection(); user = userDao.getLoginUser(connection, userCode); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }finally { BaseDao.closeResource(connection,null ,null ); } return user; } }
==bug1:==
1 java.sql.SQLException: Access denied for user '' @'localhost' (using password: YES)
错误原因:
BaseDao里面
1 username = properties.getProperty("username" );
对应的db.properties
1 2 user =root password =123456
注意配置文件里的名字要和BaseDao一致!!!
==bug2:==
1 java.sql.SQLException: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time
错误原因:
需要在配置文件的url里面加上时区!!!
1 url =jdbc:mysql://localhost:3306/smbms?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
6. 业务层接口 1 2 3 4 5 6 7 8 9 10 11 12 package com.pans.service.user;import com.pans.pojo.User;import java.sql.SQLException;public interface UserService { public User login (String userCode,String password) throws Exception; }
7. 业务层实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 package com.pans.service.user;import com.pans.dao.BaseDao;import com.pans.dao.user.UserDao;import com.pans.dao.user.UserDaoImpl;import com.pans.pojo.User;import org.junit.Test;import java.sql.Connection;import java.sql.SQLException;public class UserServiceImpl implements UserService { private UserDao userDao; public UserServiceImpl () { userDao = new UserDaoImpl (); } @Override public User login (String userCode, String password) { Connection connection = null ; User user = new User (); try { connection = BaseDao.getConnection(); user = userDao.getLoginUser(connection, userCode); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }finally { BaseDao.closeResource(connection,null ,null ); } return user; } @Test public void test () { UserServiceImpl userService = new UserServiceImpl (); User admin = userService.login("wen" , "123" ); System.out.println(admin.getUserPassword()); } }
8. 编写Servlet处理请求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 package com.pans.servlet.user;import com.pans.pojo.User;import com.pans.service.user.UserServiceImpl;import com.pans.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 { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("ServletLogin===========start!!" ); String userCode = req.getParameter("userCode" ); String password = req.getParameter("userPassword" ); UserServiceImpl userService = new UserServiceImpl (); User user = userService.login(userCode, password); if (user!=null ){ if (user.getUserPassword().equals(password)){ req.getSession().setAttribute(Constants.USER_SESSION,user); resp.sendRedirect("jsp/frame.jsp" ); }else { req.setAttribute("error" ,"密码错误!" ); req.getRequestDispatcher("login.jsp" ).forward(req,resp); } }else { req.setAttribute("error" ,"用户名不存在" ); req.getRequestDispatcher("login.jsp" ).forward(req,resp); } } }
9. 添加servlet依赖 1 2 3 4 5 6 7 8 <servlet > <servlet-name > LoginServlet</servlet-name > <servlet-class > com.pans.servlet.user.LoginServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > LoginServlet</servlet-name > <url-pattern > /login.do</url-pattern > </servlet-mapping >
4、登录功能优化 1、注销功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package com.pans.servlet.user;import com.pans.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 LoginoutServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.getSession().removeAttribute(Constants.USER_SESSION); resp.sendRedirect(req.getContextPath()+"/login.jsp " ); } }
1 2 3 4 5 6 7 8 9 <servlet > <servlet-name > LoginoutServlet</servlet-name > <servlet-class > com.pans.servlet.user.LoginoutServlet</servlet-class > </servlet > <servlet-mapping > <servlet-name > LoginoutServlet</servlet-name > <url-pattern > /jsp/logout.do</url-pattern > </servlet-mapping >
2、登录拦截
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package com.pans.filter;import com.pans.pojo.User;import com.pans.util.Constants;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class SysFilter implements Filter { @Override public void init (FilterConfig filterConfig) throws ServletException { Filter.super .init(filterConfig); } @Override public void destroy () { Filter.super .destroy(); } @Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest request1 = (HttpServletRequest) request; HttpServletResponse response1 = (HttpServletResponse) response; User user = (User) request1.getSession().getAttribute(Constants.USER_SESSION); if (user==null ){ response1.sendRedirect("/smbms/error.jsp" ); }else { chain.doFilter(request,response); } } }
1 2 3 4 5 6 7 8 9 <filter > <filter-name > SysFilter</filter-name > <filter-class > com.pans.filter.SysFilter</filter-class > </filter > <filter-mapping > <filter-name > SysFilter</filter-name > <url-pattern > /jsp/*</url-pattern > </filter-mapping >
==此时遇到一个bug:==
1 class org .apache.catalina.connector.RequestFacade cannot be cast to class javax .servlet.http.HttpServletResponse (org.apache.catalina.connector.RequestFacade and javax.servlet.http.HttpServletResponse are in unnamed module of loader java.net.URLClassLoader @33723e30 )
经过检查发现在过滤器中==类型转换错误:==
1 HttpServletResponse response1 = (HttpServletResponse) response;
写成了:==(由于使用了快速提示没有注意到名字!)==
1 HttpServletResponse response1 = (HttpServletResponse) resquest;
3、修改密码
导入/编写前端js界面
理清思路架构
UserDao接口
1 2 public int updatePwd (Connection connection,String userCode,String password) throws SQLException;
UserDao实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 @Override public int updatePwd (Connection connection,String userCode, String password) throws SQLException { int rows=0 ; if (connection!=null ){ String sql="update smbms_user set userPassword=? where userCode=?" ; PreparedStatement preparedStatement=null ; Object[] params = {password,userCode}; rows = BaseDao.execute(connection,preparedStatement,sql,params); BaseDao.closeResource(connection,preparedStatement,null ); } return rows; }
Service接口
1 2 public boolean updatePwd (String userCode,String password) ;
Service实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Override public boolean updatePwd (String userCode, String password) { boolean flag=false ; Connection connection = null ; try { connection = BaseDao.getConnection(); if (userDao.updatePwd(connection,userCode,password)>0 ){ flag=true ; } } catch (SQLException | ClassNotFoundException e) { e.printStackTrace(); } finally { BaseDao.closeResource(connection,null ,null ); } return flag; }
Servlet实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 package com.pans.servlet.user;import com.pans.pojo.User;import com.pans.service.user.UserServiceImpl;import com.pans.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 updatePwd extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Object attribute = req.getSession().getAttribute(Constants.USER_SESSION); String newpassword = req.getParameter("newpassword" ); boolean flag=false ; if (attribute!=null &&newpassword!=null &&newpassword.length()!=0 ){ UserServiceImpl userService = new UserServiceImpl (); flag=userService.updatePwd(((User)attribute).getUserCode(),newpassword); if (flag){ req.setAttribute("message" ,"密码修改成功,请返回重新登录!" ); req.getSession().removeAttribute(Constants.USER_SESSION); resp.sendRedirect("/smbms/login.jsp" ); } }else { req.setAttribute("message" ,"密码修改失败!" ); req.getRequestDispatcher("pwdmodify.jsp" ).forward(req,resp); } } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
4、Ajax验证旧密码
导入相关依赖
1 2 3 4 5 6 阿里巴巴工具转换(map-->json) <dependency > <groupId > com.alibaba</groupId > <artifactId > fastjson</artifactId > <version > 1.2.75</version > </dependency >
旧密码验证只需要在前端验证(旧密码从Session中获得)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 public void pwdModify (HttpServletRequest req, HttpServletResponse resp) { String oldPassword = req.getParameter("oldpassword" ); Object attribute = req.getSession().getAttribute(Constants.USER_SESSION); String userRealPassword = ((User) attribute).getUserPassword(); Map<String, String> resultMap = new HashMap <String,String>(); if (attribute==null ){ resultMap.put("result" ,"sessionerror" ); }else if (StringUtils.isNullOrEmpty(oldPassword)){ resultMap.put("result" ,"error" ); }else { if (oldPassword.equals(userRealPassword)){ resultMap.put("result" ,"true" ); }else { resultMap.put("result" ,"false" ); } } resp.setContentType("application/json" ); try { PrintWriter writer = resp.getWriter(); writer.write(JSONArray.toJSONString(resultMap)); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } 前端响应结果为:{"result" :"true/false/..." }
复用servlet(==因为在前端中的action路径都是该servlet的路径==)
1 2 3 4 5 6 7 8 9 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("savepwd" )){ this .updatePassword(req,resp); } }
==注意js文件渲染后的乱码问题:==将js文件用文本打开,然后另存为的时候选择utf-8 BOOM编码格式即可!!!