Hướng dẫn đăng nhập trên trang chủ và trang quản trị Spring MVC-MongoDB
Đăng lúc: 05:58 PM - 21/03/2024 bởi Charles Chung - 1070Trang bài này tôi sẽ hướng dẫn các bạn cách tổ chức project với phần dành cho người dùng và phần danh cho quản trị, đăng nhập, đăng xuất trên trang chủ và trang quản trị. Có cả source code làm việc với SQL Server
1. Kiến thức cần có
- Thiết kế web với HTML5, CSS3, JS, JQuery, Bootstrap
- Cơ bản về MongoDB
- Nắm vững JavaCore
- Nắm cơ bản về JSP Servlet, Spring MVC
2. Chuẩn bị dữ liệu
3. Các chức năng trong bài viết
- Tạo Layout trang chủ dành cho người dùng
- Đăng nhâp, đăng xuất trang người dùng
- Tạo Layout trang admin dành cho quản trị
- Đăng nhập, đăng xuất trang quản trị
4. Các bước thực hiện
Bước 1: Tạo dự án
Mở Eclipse tạo loại project Dynamic Web Project và đặt tên "SpringMVCAuthentication", lưu ý sinh file web.xml trong quá trình tạo
Bước 2: Convert project sang Maven Project
Kích chuột phải vào project vừa tạo -> chọn Configure->Convert to Maven Project -> Finish
Bước 3: Mở file pom.xml và cấu hình các dependency như sau
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 |
<dependencies> <!-- spring dependency --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!-- jstl dependency --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>3.4.9</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>3.12.14</version> </dependency> </dependencies> |
Bước 4: Copy thư mục resources đã tải về vào thư mục src/main/webapp của project
Bước 5: Tạo tệp tin spring-servlet.xml trong thư mục src/main/webapp/WEB-INF và cấu hình như sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <!-- chỉ ra các package chứa các lớp java được đăng ký như là các bean --> <context:component-scan base-package="com.hanam88" /> <!-- chỉ tìm kiếm các bean trong cùng context application mà nó được định nghĩa --> <context:annotation-config /> <!-- mặc định các basic components được ủy quyền gửi request tới các controller --> <mvc:annotation-driven /> <!-- Cấu hình đường dẫn tài nguyên được phép truy cập --> <mvc:resources mapping="/**" location="/resources/" /> <!-- Tạo bean xác định view sẽ được sinh ra (thư mục chứa các view, đuôi tệp tin view) --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/views/" p:suffix=".jsp" /> </beans> |
Bước 6: Mở tệp tin web.xml ở thư mục src/main/webapp/WEB-INF và cấu hình vào trong thẻ web-app như sau
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 |
<!-- Cấu hình filter hỗ trợ UTF-8 --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Cấu hình Dispatcher Servlet nhận các cấu hình của Spring trong file spring-servlet.xml --> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> |
Bước 7: Tạo các trang jsp để hiển thị dữ liệu và các lớp entities, services, controller,... để xử lý logic
- Cấu trúc thư mục các gói và các lớp, giao diện xử lý logic
- Cấu trúc thư mục các tài nguyên và các trang jsp
- Tạo lớp com.hanam88.entities/Account.java (Biểu diễn dữ liệu collection account)
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 |
package com.hanam88.entities; import java.io.Serializable; public class Account implements Serializable { private static final long serialVersionUID = 1L; private String id; private String username; private String password; private String fullname; private String role; private String picture; private boolean status; public Account() { } public Account(String id, String username, String password, String fullname, String role, String picture, boolean status) { super(); this.id = id; this.username = username; this.password = password; this.fullname = fullname; this.role = role; this.picture = picture; this.status = status; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getFullname() { return fullname; } public void setFullname(String fullname) { this.fullname = fullname; } public String getRole() { return role; } public void setRole(String role) { this.role = role; } public String getPicture() { return picture; } public void setPicture(String picture) { this.picture = picture; } public boolean isStatus() { return status; } public void setStatus(boolean status) { this.status = status; } } |
- Tạo lớp com.hanam88.factory/MongoFactory.java (Chứa nghiệp vụ kết nối với mongodb)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package com.hanam88.factory; import com.mongodb.MongoClient; import com.mongodb.client.MongoDatabase; public class MongoFactory { private static MongoClient mongo; private MongoFactory() { } public static MongoClient getInstance() { int port = 27017; String hostname = "localhost"; if (mongo == null) { try { mongo = new MongoClient(hostname, port); } catch (Exception e) { e.printStackTrace(); } } return mongo; } public static MongoDatabase getDatabase() { return getInstance().getDatabase("hanam88"); } } |
- Tạo lớp com.hanam88.util/Cipher.java (Chứa nghiệp vụ mã hóa MD5)
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 |
package com.hanam88.util; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class Cipher { public static String GenerateMD5(String data){ try { // gọi phương thức tạo đối tượng mã hóa MD5 MessageDigest md = MessageDigest.getInstance("MD5"); //chuyển chuỗi mã hóa về dạng byte byte[] messageDigest = md.digest(data.getBytes()); //chuyển mảng byte thành ký số BigInteger no = new BigInteger(1, messageDigest); // convert thành chuỗi hexa 16 String hashtext = no.toString(16); while (hashtext.length() < 32) { hashtext = "0" + hashtext; } return hashtext; } catch (NoSuchAlgorithmException ex) { System.out.println("Sai tên giải thuật"); } return null; } } |
- Tạo lớp com.hanam88.services/AccountService.java (Chứa nghiệp vụ làm việc với collection account)
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.hanam88.services; import org.bson.BsonDocument; import org.bson.BsonString; import org.bson.Document; import org.bson.conversions.Bson; import org.springframework.stereotype.Service; import com.hanam88.entities.Account; import com.hanam88.factory.MongoFactory; import com.mongodb.client.MongoCollection; @Service("accountService") public class AccountService { // phương thức lấy Account theo username public Account getAccount(String username) { MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("account"); Bson filter = new BsonDocument("username", new BsonString(username)); Document doc = collection.find(filter).first(); if (doc != null) return new Account(doc.getObjectId("_id").toString(), doc.getString("username"), doc.getString("password"), doc.getString("fullname"), doc.getString("role"), doc.getString("picture"),doc.getBoolean("status")); else return null; } } |
- Tạo lớp com.hanam88.controllers/UserController.java (Chứa nghiệp vụ xử lý trên trang người dùng)
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 |
package com.hanam88.controllers; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.hanam88.entities.Account; import com.hanam88.services.AccountService; import com.hanam88.util.Cipher; @Controller public class UserController { @Resource(name = "accountService") AccountService accountService; //GET: trang-chu @RequestMapping(value = { "", "trang-chu" }) public String index(Model model) { model.addAttribute("page", "index"); return "home"; } //GET: gioi-thieu @RequestMapping(value = "gioi-thieu") public String about(Model model) { model.addAttribute("page", "about"); return "home"; } //GET: dang-nhap @RequestMapping(value = "dang-nhap", method = RequestMethod.GET) public String login(Model model) { model.addAttribute("page", "login"); return "home"; } //POST: dang-nhap (xử lý đăng nhập) @RequestMapping(value = "dang-nhap", method = RequestMethod.POST) public String loginProcess(String username, String password, Model model, HttpServletRequest req) { Account acc = accountService.getAccount(username); String passMd5 = Cipher.GenerateMD5(password); if (acc == null || !acc.getPassword().equals(passMd5)) { model.addAttribute("msg", "Thông tin đăng nhập sai"); model.addAttribute("page", "login"); return "home"; } HttpSession session = req.getSession(); session.setMaxInactiveInterval(3600); session.setAttribute("userid", acc.getId()); session.setAttribute("picture", acc.getPicture()); System.out.println(acc.getPicture()); session.setAttribute("fullname", acc.getFullname()); return "redirect:/trang-chu"; } //GET: thoat @RequestMapping(value = "thoat") public String logout(Model model, HttpServletRequest req) { HttpSession session = req.getSession(); session.invalidate(); return "redirect:/dang-nhap"; } } |
- Tạo lớp com.hanam88.filters/AuthenticationFilter.java (Chặn các request tới đường dẫn /admin/* để kiểm tra xem người dùng đã login chưa - lưu ý lúc tạo filter nhớ để urlPattern="/admin/*"), dưới đây là code xử lý trong phương thức doFilter
1 2 3 4 5 6 7 8 9 10 11 12 |
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub // place your code here HttpServletRequest req=(HttpServletRequest)request; HttpServletResponse res=(HttpServletResponse)response; HttpSession session=req.getSession(); String uri=req.getRequestURI(); if((session==null || session.getAttribute("adminid")==null) && !uri.contains("admin/login")) res.sendRedirect(req.getContextPath()+"/admin/login"); // pass the request along the filter chain chain.doFilter(request, response); } |
- Tạo lớp com.hanam88.controllers.admin/AccountController.java (Chứa nghiệp vụ xử lý trên trang admin)
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 |
package com.hanam88.controllers.admin; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.hanam88.entities.Account; import com.hanam88.services.AccountService; import com.hanam88.util.Cipher; @Controller @RequestMapping("admin") public class AdminController { @Resource(name = "accountService") AccountService accountService; //GET: admin @RequestMapping(value = "") public String index(Model model) { model.addAttribute("page", "index"); return "homeadmin"; } //GET: san-pham @RequestMapping(value = "san-pham") public String getProduct(Model model) { model.addAttribute("page", "product"); return "homeadmin"; } //GET: admin/login @RequestMapping(value = "login", method = RequestMethod.GET) public String login(Model model) { return "admin/login"; } //POST: admin/login (xử lý login) @RequestMapping(value = "login", method = RequestMethod.POST) public String loginProcess(String username, String password, Model model, HttpServletRequest req) { Account acc = accountService.getAccount(username); String passMd5 = Cipher.GenerateMD5(password); if (acc == null || !acc.getPassword().equals(passMd5) || !acc.getRole().equals("admin")) { model.addAttribute("msg", "Thông tin đăng nhập sai hoặc bạn không có quyền!"); return "admin/login"; } HttpSession session = req.getSession(); session.setMaxInactiveInterval(3600); session.setAttribute("adminid", acc.getId()); session.setAttribute("adminpicture", acc.getPicture()); session.setAttribute("adminfullname", acc.getFullname()); return "redirect:/admin"; } //GET: admin/logout @RequestMapping(value = "logout") public String logout(Model model, HttpServletRequest req) { HttpSession session = req.getSession(); session.invalidate(); return "redirect:/admin/login"; } } |
- Tạo trang src/main/webapp/WEB-INF/views/home.jsp (hiển thị bố cục trang người dùng)
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 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <c:set var="contextPath" value="${pageContext.servletContext.contextPath}" scope="session" /> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hà Nam 88</title> <link rel="stylesheet" href="${contextPath}/user/css/bootstrap.min.css" /> <link rel="stylesheet" href="${contextPath}/user/css/style.css" /> </head> </head> <body> <div class="container"> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <a class="navbar-brand" href="${contextPath}/">HANAM88</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav mr-auto"> <li class="nav-item active"><a class="nav-link" href="${contextPath}/trang-chu">Trang chủ <span class="sr-only">(current)</span></a></li> <li class="nav-item"><a class="nav-link" href="${contextPath}/gioi-thieu">Giới thiệu</a></li> </ul> <ul class="nav navbar-nav navbar-right"> <c:choose> <c:when test="${!empty sessionScope.userid}"> <li class="nav-item mr-2"><span class="nav-link">Xin chào: ${sessionScope.fullname}</span></li> <li class="nav-item mr-2"><img class="my-picture" src="${contextPath}/admin/${sessionScope.picture}" /></li> <li class="nav-item mr-2"><a class="nav-link btn btn-primary" href="${contextPath}/thoat"> Thoát</a></li> </c:when> <c:otherwise> <li class="nav-item mr-2"><a class="nav-link btn btn-success" href="${contextPath}/dang-nhap"> Đăng nhập</a></li> </c:otherwise> </c:choose> </ul> </div> </nav> <div id="content"> <c:if test="${!empty page}"> <jsp:include page="user/${page}.jsp" /> </c:if> </div> </div> <div class="container"> <div id="footer"> <p style="text-align: center; font-size: 20px;">Copyright 2024 hanam88.com</p> </div> </div> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="${contextPath}/user/js/jquery-3.7.1.min.js"></script> <script src="${contextPath}/user/js/popper.min.js"></script> <script src="${contextPath}/user/js/bootstrap.min.js"></script> <script type="text/javascript" src="${contextPath}/user/js/home.js"></script> </body> </html> |
- Tạo trang src/main/webapp/WEB-INF/views/user/login.jsp (hiển thị trang login trên trang người dùng)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <div style="width:400px;margin:auto;padding:20px;"> <h4 class="title-group">Đăng nhập</h4> <p style="color:red;">${msg}</p> <form action="${contextPath}/dang-nhap" method="post"> <div class="form-group"> <input type="text" class="form-control" placeholder="Tên đăng nhập" name="username"> </div> <div class="form-group"> <input type="password" class="form-control" placeholder="Mật khẩu" name="password"> </div> <button type="submit" class="btn btn-primary">Đăng nhập</button> </form> </div> |
- Tạo trang src/main/webapp/WEB-INF/views/user/index.jsp và about.jsp (gõ vài chữ vui vui vào nhé)
- Tạo trang src/main/webapp/WEB-INF/views/homeadmin.jsp (hiển thị bố cục trang quản trị)
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 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <c:set var="contextPath" value="${pageContext.servletContext.contextPath}" scope="session" /> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Trang quản trị</title> <link rel="stylesheet" href="${contextPath}/user/css/bootstrap.min.css" /> <link rel="stylesheet" href="${contextPath}/admin/css/style.css" /> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-lg-3"> <div id="left-bar"> <h2>HANAM88</h2> <ul> <li><a href="#">Quản lý loại sản phẩm</a></li> <li><a href="${contextPath}/admin/san-pham">Quản lý sản phẩm</a></li> <li><a href="#">Quản lý đơn hàng</a></li> </ul> </div> </div> <div class="col-lg-9"> <div class="col-lg-12"> <div id="heading"> <c:if test="${!empty sessionScope.adminid}"> Xin chào: ${sessionScope.adminfullname} <img class="my-picture" src="${contextPath}/admin/${sessionScope.adminpicture}" /></c:if> <a class="btn btn-info" href="${contextPath}/admin/logout">Thoát</a> </div> </div> <div class="col-lg-12"> <div id="content"> <c:if test="${!empty page}"> <jsp:include page="admin/${page}.jsp" /> </c:if> </div> </div> </div> </div> </div> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="${contextPath}/user/js/jquery-3.7.1.min.js"></script> <script src="${contextPath}/user/js/popper.min.js"></script> <script src="${contextPath}/user/js/bootstrap.min.js"></script> <script type="text/javascript" src="${contextPath}/admin/js/admin.js"></script> </body> </html> |
- Tạo trang src/main/webapp/WEB-INF/views/admin/login.jsp (hiển thị trang login trên trang quản trị)
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 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Đăng nhập</title> <link rel="stylesheet" href="${pageContext.servletContext.contextPath}/user/css/bootstrap.min.css" /> </head> <body> <div style="width:400px;margin:auto;padding:20px;"> <h4>Đăng nhập</h4> <p style="color:red;">${msg}</p> <form action="${pageContext.servletContext.contextPath}/admin/login" method="post"> <div class="form-group"> <input type="text" class="form-control" placeholder="Tên đăng nhập" name="username"> </div> <div class="form-group"> <input type="password" class="form-control" placeholder="Mật khẩu" name="password"> </div> <button type="submit" class="btn btn-primary">Đăng nhập</button> </form> </div> </body> </html> |
- Tạo trang src/main/webapp/WEB-INF/views/admin/index.jsp và product.jsp (gõ vài chữ vui vui vào nhé)
Bước 8: Run và kiểm tra kết quả
- Màn hình login trên trang chủ (sai thông báo lỗi)
- Màn hình đăng nhập thành công trang chủ (hiển thị thông tin người dùng và nút thoát)
- Màn hình login trên trang quản trị (nếu người dùng cố tình vào admin thì ứng dụng sẽ điều hướng ra trang login, dưới đây là màn hình login sai thông báo lỗi, hoặc không có quyền thông báo lỗi)
- Màn hình đăng nhập thành công trang admin (hiển thị thông tin người dùng và nút thoát)
Link tải source code với MongoDB
Link tải source code với SQL Server
Video đang quay...
thay lời cảm ơn!
Các bài cũ hơn
- Hướng dẫn xây dựng Layout trang User và Admin trong Spring MVC (07:25 PM - 18/03/2024)
- Xử lý giỏ hàng trong Spring MVC Hibernate-SQL Server (02:22 PM - 11/03/2024)
- Hướng dẫn các thao tác cơ bản với MongoDB trong Spring MVC-Maven-Eclipse (11:47 AM - 04/03/2024)
- Các thao tác cơ bản CRUD-Tìm kiếm-Phân trang trong Spring MVC-Hibernate-SQL Server (11:41 PM - 28/02/2024)
- [Java-Web] Tìm hiểu về đa ngôn ngữ với Internationalization và Localization trong JSP Servlet sử dụng thư viện JSTL (04:50 PM - 26/02/2024)