SMBMS项目实战(登录功能实现)
流程图:
1)编写前端界面
2)在web.xml中设置欢迎页面(首页)
1 <!-- 设置欢迎页面--> 2 <welcome-file-list> 3 <welcome-file>login.jsp</welcome-file> 4 </welcome-file-list>
3)编写dao层登录用户登录的接口
1 // 设置为面向接口编程的格式 2 public interface UserDao { 3 // 得到登录的用户 4 public User getLoginUser(Connection connection, String userCode) throws SQLException; 5 }
4)编写dao接口的实现类
1 package com.mine.dao.user; 2 3 import com.mine.dao.BaseDao; 4 import com.mine.pojo.User; 5 6 import java.sql.Connection; 7 import java.sql.PreparedStatement; 8 import java.sql.ResultSet; 9 import java.sql.SQLException; 10 11 public class UserDaoImpl implements UserDao { 12 // 去数据库中查询得到用户 13 public User getLoginUser(Connection connection, String userCode) throws SQLException { 14 15 // 1)准备三个对象 16 PreparedStatement pstm = null; // 因为下面执行函数execute需要这两个参数,所以在这初始化 17 ResultSet rs = null; // 结果 18 User user = null; // 可能会查出来的用户 19 20 21 // 2)判断数据库连接是否成功 22 if (connection != null) { 23 // 3)如果连接成功了,丢一个sql 24 String sql = "select * from smbms_user where userCode=?"; // 用问号保证安全 25 Object[] params = {userCode}; // 封装参数,它就是唯一的数据 26 27 // 4)执行sql 28 // sql也好了,userCode也好了,接下来需要PreparedStatement和ResultSet就可以调用执行方法了 29 rs = BaseDao.execute(connection, pstm, rs, sql, params); 30 // 遍历用户信息 31 if (rs.next()) { 32 user = new User(); // new 一个User对象 33 user.setId(rs.getInt("id")); // 设置id为查出来的对象的id 34 user.setUserCode(rs.getString("userCode")); 35 user.setUserName(rs.getString("userName")); 36 user.setUserPassword(rs.getString("userPassword")); 37 user.setGender(rs.getInt("gender")); 38 user.setBirthday(rs.getDate("birthday")); 39 user.setPhone(rs.getString("phone")); 40 user.setAddress(rs.getString("address")); 41 user.setUserRole(rs.getInt("userRole")); 42 user.setCreatedBy(rs.getInt("createdBy")); 43 user.setCreationDate(rs.getTimestamp("creationDate")); 44 user.setModifyBy(rs.getInt("modifyBy")); 45 user.setModifyDate(rs.getTimestamp("modifyDate")); 46 } 47 // 上面这些是从数据库查出来的,查完要关闭数据库 48 BaseDao.closeResource(null, pstm, rs); 49 // 最后返回user 50 51 52 } 53 return user; 54 55 } 56 }
5)业务层接口
1 public interface UserService { 2 // 用户登录,去公司写的大多就是这个业务层 3 public User login(String userCode, String password) throws SQLException; 4 }
6)业务层实现类
1 package com.mine.service.user; 2 3 import com.mine.dao.BaseDao; 4 import com.mine.dao.user.UserDao; 5 import com.mine.dao.user.UserDaoImpl; 6 import com.mine.pojo.User; 7 import org.junit.Test; 8 9 import java.sql.Connection; 10 import java.sql.SQLException; 11 12 public class UserServiceImpl implements UserService { 13 // 业务层都会调用dao层,所以我们要引入dao层; 14 private UserDao userDao; 15 public UserServiceImpl() { 16 userDao = new UserDaoImpl(); 17 } 18 /* 19 userCode:用户名 20 password:密码 21 22 */ 23 // 调这个方法的人就能拿到用户 24 public User login(String userCode, String password) { 25 Connection connection = null; 26 User user = null; 27 28 29 try { 30 connection = BaseDao.getConnection(); // 建立连接 31 // 通过业务层调用对应的具体的数据库操作 32 user = userDao.getLoginUser(connection, userCode); 33 } catch (SQLException e) { 34 e.printStackTrace(); 35 } finally { 36 BaseDao.closeResource(connection, null, null); 37 } 38 return user; 39 } 40 41 @Test // 这个是在junit包里面的,所以要引入junit包 42 public void test() { 43 UserServiceImpl userService = new UserServiceImpl(); 44 User admin = userService.login("admin", "1234567"); 45 System.out.println(admin.getUserPassword()); 46 } 47 }
7)编写servlet
1 package com.mine.servlet.user; 2 3 import com.mine.pojo.User; 4 import com.mine.service.user.UserService; 5 import com.mine.service.user.UserServiceImpl; 6 import com.mine.util.Constants; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 import java.io.IOException; 13 import java.sql.SQLException; 14 15 public class LoginServlet extends HttpServlet { 16 // servlet:控制层。去调业务层的代码,要么私有进来,要么去new 17 @Override 18 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 19 System.out.println("LoginServlet -- start...."); 20 21 // 获取用户名和密码,去前端拿 22 String userCode = req.getParameter("userCode"); 23 String userPassword = req.getParameter("userPassword"); 24 25 // 和数据库中的密码进行对比,调业务层 26 UserService userService = new UserServiceImpl(); 27 try { 28 User user = userService.login(userCode, userPassword); // 这里已经把登录的人查出来 29 if (user != null) { // 查有此人,可以登录 30 // 将用户的信息放到session中 31 req.getSession().setAttribute(Constants.USER_SESSION, user); 32 // 登录成功之后跳转到内部主页 33 resp.sendRedirect("jsp/frame.jsp"); 34 35 } else { // 查无此人,无法登录 36 // 转发回登录页面,顺带提示用户名或密码错误 37 req.setAttribute("error", "用户名或密码不正确"); 38 req.getRequestDispatcher("login.jsp").forward(req, resp); 39 40 } 41 } catch (SQLException e) { 42 e.printStackTrace(); 43 } 44 45 46 } 47 48 @Override 49 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 50 doGet(req, resp); 51 } 52 }
上面代码中的
Constants.USER_SESSION
8)注册servlet
1 <!--Servlet--> 2 <servlet> 3 <servlet-name>LoginServlet</servlet-name> 4 <servlet-class>com.mine.servlet.user.LoginServlet</servlet-class> 5 </servlet> 6 <servlet-mapping> 7 <servlet-name>LoginServlet</servlet-name> 8 <url-pattern>/login.do</url-pattern> 9 </servlet-mapping> 10
9)测试访问,确保以上成功
出现bug:用户名和密码都正确,但是就是没有跳转到下一个页面,而是提示错误
错误信息:java.sql.SQLException: No suitable driver found for jdbc:mysql:/localhost:3306?useUnicode=true&characterEncoding=utf-8
preparedStatement = connection.prepareStatement(sql)和resultSet = preparedStatement.executeQuery(sql)是功能相同的两行代码。所以会报错。
登录功能优化:
注销功能:思路:移除session,返回登录页面
1 package com.mine.servlet.user; 2 3 import com.mine.util.Constants; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 import java.io.IOException; 10 11 public class LogoutServlet extends HttpServlet { 12 @Override 13 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 14 // 移除用户的session 15 req.getSession().removeAttribute(Constants.USER_SESSION); 16 // 回到登录页面 17 resp.sendRedirect("/login.jsp"); 18 } 19 20 @Override 21 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 22 doGet(req, resp); 23 } 24 }
注册
1 <servlet> 2 <servlet-name>LogoutServlet</servlet-name> 3 <servlet-class>com.mine.servlet.user.LogoutServlet</servlet-class> 4 </servlet> 5 <servlet-mapping> 6 <servlet-name>LogoutServlet</servlet-name> 7 <url-pattern>/jsp/logout.do</url-pattern> 8 </servlet-mapping>
出现bug 404
解决方案:
登录拦截优化:
编写一个过滤器
1 package com.mine.filter; 2 3 import com.mine.pojo.User; 4 import com.mine.util.Constants; 5 6 import javax.servlet.*; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 import java.io.IOException; 10 import java.net.HttpRetryException; 11 import java.net.http.HttpRequest; 12 import java.net.http.HttpResponse; 13 14 public class SysFilter implements Filter { 15 @Override 16 public void init(FilterConfig filterConfig) throws ServletException { 17 18 } 19 20 @Override 21 public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { 22 HttpServletRequest request = (HttpServletRequest) req; // 这个为了获取session 23 HttpServletResponse response = (HttpServletResponse) resp; // 这个为了重定向 24 25 // 过滤器从session中获取用户,如果把session移除掉,它一定获取不到 26 User user = (User) request.getSession().getAttribute(Constants.USER_SESSION); 27 28 if (user == null) { // 如果用户为空,说明session已经被移除或者注销了或者未登录,那就让它走error.jsp 29 response.sendRedirect("/smbms/error.jsp"); 30 31 } else { 32 chain.doFilter(req, resp); 33 } 34 } 35 36 @Override 37 public void destroy() { 38 39 } 40 }
配置
1 <!-- 用户登录过滤器--> 2 <filter> 3 <filter-name>SysFilter</filter-name> 4 <filter-class>com.mine.filter.SysFilter</filter-class> 5 </filter> 6 <filter-mapping> 7 <filter-name>SysFilter</filter-name> 8 <url-pattern>/jsp/*</url-pattern> <!-- jsp下面的所有页面 --> 9 </filter-mapping>
注:如果error.jsp访问找不到资源,把error改个名即可访问
bug:
posted on 2021-04-24 13:48 Love&Share 阅读(571) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~