Xử lý giỏ hàng trong Spring MVC Hibernate-SQL Server
Đăng lúc: 02:22 PM - 11/03/2024 bởi Charles Chung - 1895Trong bài này tôi sẽ hướng dẫn các bạn các thao tác cơ bản về xử lý giỏ hàng trong Spring MVC Hiberate-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ề SQL Server
- Nắm vững JavaCore
- Nắm cơ bản về JSP Servlet, Spring MVC
2. Chuẩn bị dữ liệu
- Tải tệp script tạo cơ sở dữ liệu trong SQL Server tại đây
- Tải thư mục images chứa các ảnh sách tại đây
3. Các chức năng trong bài viết
- Hiển thị danh mục sách và sách trên trang chủ
- Hiển thị sách theo danh mục chọn
- Xem chi tiết sách
- Thêm vào giỏ hàng
- Đăng nhập
- Hiển thị thông tin người dùng kèm logout
- Hiển thị nút giỏ hàng với tổng số sách bên trong
- Hiển thị thông tin chi tiết các sản phẩm trong giỏ hàng
- Đặt hàng
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 "SpringMVCHibernateSQLServerCartItem", 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 27 28 29 30 31 32 33 34 35 36 37 38 |
<dependencies> <!-- https://mvnrepository.com/artifact/javax.servlet/jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!--https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.18</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.18</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>5.3.18</version> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.4.26.Final</version> </dependency> <!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc --> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>12.5.0.jre11-preview</version> </dependency> </dependencies> |
Bước 4: Copy thư mục images đã tải về vào thư mục src/main/webapp/resources của project (chưa có resources thì tạo ra nhé)
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 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<?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.controllers,com.hanam88.services" /> <!-- 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" /> <!-- Tạo đối tượng bean dataSource kết nối database oracle --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"></property> <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=BookStore;Encrypt=True;trustServerCertificate=True"></property> <property name="username" value="sa"></property> <property name="password" value="123465"></property> </bean> <!-- Tạo đối tượng bean sessionFactory cấu hình Hibernate --> <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="packagesToScan" value="com.hanam88.entities"></property> <property name="hibernateProperties"> <props> <prop key="hibernate.current_session_context_class">thread</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop> </props> </property> </bean> </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, dao, controller để xử lý logic
Tạo thư mục views trong thư mục src/main/webapp/WEB-INF để chứa các trang jsp, sau đây là cấu trúc project đầy đủ
- Cấu trúc chi tiết phần services và controller
- Cấu trúc chi tiết phần views
- Tạo lớp com.hanam88.enitities/Category.java để map với bảng Categories
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 |
package com.hanam88.entities; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="Categories") public class Category implements Serializable{ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int categoryId; private String categoryName; public Category() { } public Category(int categoryId, String categoryName) { super(); this.categoryId = categoryId; this.categoryName = categoryName; } public int getCategoryId() { return categoryId; } public void setCategoryId(int categoryId) { this.categoryId = categoryId; } public String getCategoryName() { return categoryName; } public void setCategoryName(String categoryName) { this.categoryName = categoryName; } } |
- Tạo lớp com.hanam88.enitities/Account.java để map với bảng 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 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 98 99 100 101 102 103 |
package com.hanam88.entities; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="Account") public class Account implements Serializable{ private static final long serialVersionUID = 1L; @Id private String accountId; private String username; private String password; private String fullName; private String picture; private String email; private String address; private String phone; private boolean isAdmin; private boolean active; public Account(String accountId, String username, String fullName,String password, String picture, String email, String address, String phone, boolean isAdmin, boolean active) { super(); this.accountId = accountId; this.username = username; this.password = password; this.fullName=fullName; this.picture = picture; this.email = email; this.address = address; this.phone = phone; this.isAdmin = isAdmin; this.active = active; } public Account() { } public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } public String getAccountId() { return accountId; } public void setAccountId(String accountId) { this.accountId = accountId; } 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 getPicture() { return picture; } public void setPicture(String picture) { this.picture = picture; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public boolean isAdmin() { return isAdmin; } public void setAdmin(boolean isAdmin) { this.isAdmin = isAdmin; } public boolean isActive() { return active; } public void setActive(boolean active) { this.active = active; } } |
- Tạo lớp com.hanam88.entities/Basket.java để biểu diễn dữ liệu giỏ hà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 |
package com.hanam88.entities; import java.io.Serializable; public class Basket implements Serializable { private static final long serialVersionUID = 1L; private String bookId; private String title; private float price; private int quantity; public Basket() { } public Basket(String bookId, String title, float price, int quantity) { super(); this.bookId = bookId; this.title = title; this.price = price; this.quantity = quantity; } public String getBookId() { return bookId; } public void setBookId(String bookId) { this.bookId = bookId; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } } |
- Tương tự tạo các lớp còn lại trong com.hanam88.entities
- Tạo giao diện com.hanam88.services.dao/GenericDao.java
1 2 3 4 5 6 7 8 9 10 11 12 |
package com.hanam88.services.dao; import java.util.List; public interface GenericDao<T,K> { public List<T> getAll(); public List<T> search(String name); public T get(K key); public boolean insert(T obj); public boolean update(T obj); public boolean delete(K key); } |
- Tạo các giao diện thực thi từ GenericDao theo gợi ý sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public interface BookDao extends GenericDao<Book, String> { public List<Category> getByCategory(int categoryId); } public interface AccountDao extends GenericDao<Account, String> { public Account getAccount(String username); } public interface CategoryDao extends GenericDao<Category, Integer> { } public interface OrderDao extends GenericDao<OrderBook, String> { public boolean insertOrderDetail(OrderBook order, List<OrderDetail> details ); } public interface PublisherDao extends GenericDao<Publisher, Integer> { } |
- Tạo lớp com.hanam88.services.dao/AccountImpl.java thực thi từ inteface AccountDao và bổ sung code sau (lưu ý sử dụng @Repository cho các lớp imlement nhé)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Autowired SessionFactory sessionFactory; @Override public Account getAccount(String username) { Session session=sessionFactory.openSession(); Query query=session.createQuery("from Account where userName=?1"); Account data=null; try { data=(Account)query.setParameter(1, username).getSingleResult(); } catch (Exception e) { e.printStackTrace(); } session.close(); return data; } |
- Tạo lớp com.hanam88.services.dao/BookImpl.java thực thi từ inteface BookDao và bổ sung code 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 |
@Autowired SessionFactory sessionFactory; @Override public List<Book> getAll() { Session session = sessionFactory.openSession(); Query query = session.createQuery("from Book"); List data = query.getResultList(); session.close(); return data; } @Override public Book get(String key) { Session session = sessionFactory.openSession(); Query query = session.createQuery("from Book where bookId=?1"); Book data = (Book) query.setParameter(1, key).getSingleResult(); session.close(); return data; } @Override public List<Category> getByCategory(int categoryId) { Session session = sessionFactory.openSession(); Query query = session.createQuery("from Book where categoryId=?1"); List data = query.setParameter(1, categoryId).getResultList(); session.close(); return data; } |
- Tạo lớp com.hanam88.services.dao/CategoryImpl.java thực thi từ inteface CategoryDao và bổ sung code sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
@Autowired SessionFactory sessionFactory; @Override public List<Category> getAll() { Session session=sessionFactory.openSession(); Query query=session.createQuery("from Category"); List data=query.getResultList(); session.close(); return data; } @Override public Category get(Integer key) { Session session=sessionFactory.openSession(); Query query=session.createQuery("from Category where categoryId=?1"); query.setParameter(1, key); Category data=(Category)query.getSingleResult(); session.close(); return data; } |
- Tạo lớp com.hanam88.services.dao/OrderImpl.java thực thi từ inteface OrderDao và bổ sung code 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 32 33 34 35 36 37 38 39 |
@Autowired SessionFactory sessionFactory; @Override public List<OrderBook> getAll() { Session session = sessionFactory.openSession(); Query query = session.createQuery("from OrderBook"); List data = query.getResultList(); session.close(); return data; } @Override public boolean insert(OrderBook obj) { Session session = sessionFactory.openSession(); session.beginTransaction(); session.save(obj); session.getTransaction().commit(); session.close(); return true; } @Override public boolean insertOrderDetail(OrderBook order, List<OrderDetail> details) { try { Session session = sessionFactory.openSession(); session.beginTransaction(); session.save(order); for (OrderDetail orderDetail : details) { session.save(orderDetail); } session.getTransaction().commit(); session.close(); } catch (Exception e) { e.printStackTrace(); return false; } return true; } |
- Tạo lớp com.hanam88.services.dao/PublisherImpl.java thực thi từ inteface PublisherDao (không sử dụng nên không cần code)
- Tạo lớp com.hanam88.util/Cipher.java xử lý 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.controllers/HomeController.java xử lý các nghiệp vụ của trang web
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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
package com.hanam88.controllers; import java.sql.Date; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.hanam88.entities.Account; import com.hanam88.entities.Basket; import com.hanam88.entities.Book; import com.hanam88.entities.OrderBook; import com.hanam88.entities.OrderDetail; import com.hanam88.services.dao.AccountDao; import com.hanam88.services.dao.BookDao; import com.hanam88.services.dao.CategoryDao; import com.hanam88.services.dao.OrderDao; import com.hanam88.util.Cipher; @Controller public class HomeController { @Autowired CategoryDao categoryDao; @Autowired BookDao bookDao; @Autowired AccountDao accountDao; @Autowired OrderDao orderDao; //GET:trang-chu "lây toàn bộ sách và hiển thị view home/books" @RequestMapping(value = { "", "trang-chu" }) public String index(Model model) { model.addAttribute("title", "DANH MỤC SÁCH"); model.addAttribute("books", bookDao.getAll()); model.addAttribute("page", "books"); return "home"; } //GET: categories "lấy toàn bộ danh mục sách và hiển thị ở menu Thể loại trên view home/categories" @RequestMapping(value = "categories") public String getCategories(Model model) { model.addAttribute("categories", categoryDao.getAll()); return "home/categories"; } //GET: danh-muc-sach "lấy sách theo danh mục và hiển thị trên view home/books @RequestMapping(value = "danh-muc-sach/{id}") public String getBooks(@PathVariable("id") Integer cateId, Model model) { model.addAttribute("title", "DANH MỤC SÁCH: " +categoryDao.get(cateId).getCategoryName()); model.addAttribute("books", bookDao.getByCategory(cateId)); model.addAttribute("page", "books"); return "home"; } //GET: chi-tiet/{id} "trả về 1 sách và hiển thị trên view home/bookdetail" @RequestMapping(value = "chi-tiet/{id}") public String detail(@PathVariable("id") String bookId, Model model) { model.addAttribute("book", bookDao.get(bookId)); model.addAttribute("page", "bookdetail"); return "home"; } //GET: countItems "trả về số lượng sách trong giỏ hàng" @RequestMapping(value = "countItems") public @ResponseBody String getItems(Model model, HttpServletRequest req) { List<Basket> baskets = new ArrayList<>(); HttpSession session = req.getSession(); if (session.getAttribute("basket") != null) { baskets = (List<Basket>) session.getAttribute("basket"); } System.out.println(baskets.size()); return String.valueOf(baskets.size()); } //GET: addItem "thêm sách vào giỏ hàng và trả về tổng số sách trong giỏ" @RequestMapping(value = "addItem/{id}") public @ResponseBody String addItem(@PathVariable("id") String bookId, HttpServletRequest req) { List<Basket> baskets = new ArrayList<>(); HttpSession session = req.getSession(); Book b = bookDao.get(bookId); if (session.getAttribute("basket") == null) { Basket basket = new Basket(b.getBookId(), b.getTitle(), b.getPrice(), 1); baskets.add(basket); session.setAttribute("basket", baskets); } else { baskets = (List<Basket>) session.getAttribute("basket"); boolean duplicate = false; for (int i = 0; i < baskets.size(); i++) { Basket bs = baskets.get(i); if (bs.getBookId().equals(bookId)) { bs.setQuantity(bs.getQuantity() + 1); duplicate = true; break; } } if (duplicate) session.setAttribute("basket", baskets); else { Basket basket = new Basket(b.getBookId(), b.getTitle(), b.getPrice(), 1); baskets.add(basket); } } session.setAttribute("basket", baskets); return String.valueOf(baskets.size()); } //GET: gio-hang "trả về sách trong giỏ hàng và hiển thị trên view home/basket" @RequestMapping(value = "gio-hang") public String showBasket(Model model, HttpServletRequest req) { model.addAttribute("page", "basket"); List<Basket> baskets = new ArrayList<>(); HttpSession session = req.getSession(); if (session.getAttribute("basket") != null) { baskets = (List<Basket>) session.getAttribute("basket"); } model.addAttribute("baskets", baskets); return "home"; } //GET: updateBasket/{id}/{value} "cập nhật lại số lượng đặt trong giỏ hang" @RequestMapping(value = "updateBasket/{id}/{value}") public @ResponseBody String updateBasket(@PathVariable("id") String bookId, @PathVariable("value") Integer quantity, Model model, HttpServletRequest req) { List<Basket> baskets = new ArrayList<>(); HttpSession session = req.getSession(); if (session.getAttribute("basket") != null) { baskets = (List<Basket>) session.getAttribute("basket"); for (int i = 0; i < baskets.size(); i++) { Basket bs = baskets.get(i); if (bs.getBookId().equals(bookId)) { bs.setQuantity(quantity); break; } } } return ""; } //GET: removeItem/{id} "xóa một sách trong giỏ hang" @RequestMapping(value = "removeItem/{id}") public @ResponseBody String removeItem(@PathVariable("id") String bookId, HttpServletRequest req) { List<Basket> baskets = new ArrayList<>(); HttpSession session = req.getSession(); boolean find = false; if (session.getAttribute("basket") != null) { int i; baskets = (List<Basket>) session.getAttribute("basket"); for (i = 0; i < baskets.size(); i++) { Basket bs = baskets.get(i); if (bs.getBookId().equals(bookId)) { find = true; break; } } if (find) { baskets.remove(i); } session.setAttribute("basket", baskets); } return ""; } //GET: dang-nhap "hiển thị màn hình đăng nhập" @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 login(String username, String password, Model model, HttpServletRequest req) { Account acc = accountDao.getAccount(username); String passMd5 = Cipher.GenerateMD5(username + 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("accountid", acc.getAccountId()); session.setAttribute("picture", acc.getPicture()); session.setAttribute("address", acc.getAddress()); session.setAttribute("phone", acc.getPhone()); session.setAttribute("fullname", acc.getFullName()); return "redirect:/"; } //GET: thoat "logout" @RequestMapping(value = "thoat") public String logout(Model model, HttpServletRequest req) { HttpSession session = req.getSession(); session.invalidate(); return "redirect:/dang-nhap"; } //POST: dat-hang "xử lý đặt hang" @RequestMapping(value = "dat-hang") public String addOrder(String address, String phone, String note, Model model, HttpServletRequest req) { List<Basket> baskets=null; HttpSession session = req.getSession(); if (session.getAttribute("accountid") == null) { return "redirect:/dang-nhap"; } if (session.getAttribute("basket") != null) { baskets = (List<Basket>) session.getAttribute("basket"); String timeStamp = new SimpleDateFormat("yyMMdd-HHmmss").format(Calendar.getInstance().getTime()); OrderBook order=new OrderBook(); order.setOrderId("HD"+timeStamp); order.setAccountId(session.getAttribute("accountid").toString()); order.setOrderDate(Date.valueOf(LocalDate.now())); order.setReceiveAddress(address); order.setReceiveDate(null); order.setReceivePhone(phone); order.setNote(note); List<OrderDetail> orderdetails=new ArrayList<OrderDetail>(); for (Basket basket : baskets) { orderdetails.add(new OrderDetail("HD"+timeStamp, basket.getBookId(), basket.getQuantity(), basket.getPrice())); } orderDao.insertOrderDetail(order, orderdetails); model.addAttribute("msg","Đặt hàng thành công"); } else { model.addAttribute("msg","Giỏ hàng trống"); } model.addAttribute("page","basket"); baskets=new ArrayList<Basket>(); session.setAttribute("basket", null); model.addAttribute("baskets", baskets); return "home"; } } |
- Tạo tệp resources/css/style.css theo gợi ý 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 32 33 34 35 36 37 38 |
.title-group { padding-top:8px; padding-left:5px; padding-bottom:10px; display:block; background-color:#343a40; color:white; } #banner-slide { margin-bottom:1px; height:200px; background-image:url(../images/banner-book.jpg); background-repeat: no-repeat; background-size:100%; background-position: center; background-color:rgb(174,181,200); } #content { min-height:400px; } #footer{ height:80px; padding-top:8px; padding-left:5px; padding-bottom:10px; display:block; background-color:#343a40;; color:white; } .my-picture { width:40px; height:40px; border-radius:20px; } |
- Tạo tệp resources/js/home.js theo gợi ý 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 |
//Document ready thì show loại sách và số lượng trong giỏ hàng (jquery ajax) $(function(){ $.get(path + "/categories", function(data) { $('.dropdown-menu').html(data); }); $.get(path + "/countItems", function(data) { $('#basket_total').html(data); }); }); //hàm xử lý add 1 sách vào giỏ hàng (jquery ajax) function addBasket(bookId) { $.get(path + "/addItem/" + bookId, function(data) { $('#basket_total').html(data); window.scrollTo({ top: 0, behavior: 'smooth' }); }); } //hàm xử lý cập nhật lại số lượng trong giỏ hàng (jquery ajax) function updateBasket(bookId, value) { $.get(path + "/updateBasket/" + bookId + "/" + value, function() { window.location.reload(); }); } //hàm xử lý xóa 1 sách trong giỏ hàng (jquery ajax) function removeItem(bookId) { if (confirm('Bạn có muốn xóa không?')) { $.get(path + "/removeItem/" + bookId, function() { window.location.reload(); }); } } |
- Tạo trang views/home.jsp hiển thị cấu trúc trang chủ
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 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <c:set var="contextPath" value="${pageContext.servletContext.contextPath}" scope="request"/> <fmt:setLocale value="vi_VN" scope="session"/> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Hà Nam 88 - Kho sách hay</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="${contextPath}/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}/">SACHHAY88</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 dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Thể loại </a> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> </div></li> <li class="nav-item"><a class="nav-link" href="#">Giới thiệu</a></li> </ul> <ul class="nav navbar-nav navbar-right"> <c:choose> <c:when test="${!empty sessionScope.accountid}"> <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}/images/${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> <li class="nav-item"><a class="nav-link btn btn-danger" href="${contextPath}/gio-hang"> Giỏ hàng(<span id="basket_total"><jsp:include page="${contextPath}/countItems"></jsp:include></span>)</a></li> </ul> </div> </nav> <div id="banner-slide"></div> <div id="content"> <c:if test="${!empty page}"> <jsp:include page="home/${page}.jsp" /> </c:if> </div> </div> <div id="footer" class="container-fluid"> <p style="text-align: center; font-size: 20px;">Copyright 2024 by sachhay88.com</p> </div> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js"></script> <script> var path='${pageContext.servletContext.contextPath}'; </script> <script type="text/javascript" src="${contextPath}/js/home.js"></script> </body> </html> |
- Tạo trang views/home/books.jsp hiển thị toàn bộ sách, hoặc sách theo danh mục
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <h4 class="title-group">${title}</h4> <div class="row"> <c:forEach items="${books}" var="b"> <div class="col-sm-12 col-md-6 col-lg-4 col-xl-3"> <div class="card" style="width: 100%"> <img class="card-img-top" src="${contextPath}/images/${b.picture}" /> <div class="card-body"> <h6 class="card-title">${b.title}</h6> <p class="card-text">Giá: <fmt:formatNumber value="${b.price}" type="currency"/></p> <button onclick="addBasket('${b.bookId}')" class="btn btn-primary">Mua</button> <a href="${contextPath}/chi-tiet/${b.bookId}" class="btn btn-success">Chi tiết</a> </div> </div> </div> </c:forEach> </div> |
- Tạo trang views/home/categories.jsp hiển thị danh mục sách
1 2 3 4 5 6 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <c:forEach items="${categories}" var="c"> <a class="dropdown-item" href="${pageContext.servletContext.contextPath}/danh-muc-sach/${c.categoryId}">${c.categoryName}</a> </c:forEach> |
- Tạo trang views/home/bookdetail.jsp hiển thị chi tiết sách
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <h4 class="title-group">CHI TIẾT SẢN PHẨM</h4> <div class="row" style="padding:10px;box-sizing: border-box;"> <div class="col-3"> <img src="${contextPath}/images/${book.picture}" width="95%" /> </div> <div class="col-9"> <p>${book.title}</p> <p> Giá :<fmt:formatNumber value="${book.price}" type="currency"/> </p> </div> <div class="col-12"> <h4>Mô tả</h4> <p>${book.description}</p> </div> <button onclick="addBasket('${book.bookId}')" class="btn btn-primary">Mua</button> <a class="btn btn-success" href="javascript:history.back();">Quay lại</a> </div> |
- Tạo trang views/home/login.jsp hiển thị form đăng nhập
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 views/home/basket.jsp hiển thị giỏ hà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 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <c:set var="total" value="0" /> <div class="row"> <div class="col-md-8"> <h4 class="title-group">GIỎ HÀNG</h4> <div style="width: 100%; margin: auto; padding: 20px;"> <p style="color:red">${msg}</p> <table class="table table-bordered"> <tr> <th>Mã sách</th> <th>Tên sách</th> <th>Giá</th> <th>Số lượng</th> <th>Thành tiền</th> <th></th> </tr> <c:forEach items="${baskets}" var="b"> <tr> <td>${b.bookId}</td> <td><a href="${contextPath}/chi-tiet/${b.bookId}">${b.title}</a></td> <td><fmt:formatNumber value="${b.price}" type="currency"/></td> <td><input type="number" style="width:60px" onchange="updateBasket('${b.bookId}',this.value)" value="${b.quantity}" min="1" max="100"/></td> <td><fmt:formatNumber value="${b.price*b.quantity}" type="currency"/></td> <c:set var="total" value="${total+b.price*b.quantity}" /> <td><a href="#" class="btn btn-danger" onclick="removeItem('${b.bookId}')">Xóa</a></td> </tr> </c:forEach> </table> <h5>Tổng tiền: <fmt:formatNumber value="${total}" type="currency"/></h5> </div> </div> <div class="col-md-4"> <h4 class="title-group">Thông tin đặt hàng</h4> <form action="dat-hang" method="post"> <table> <tr> <td>Họ và tên: </td> <td>${sessionScope.fullname}</td> </tr> <tr> <td>Địa chỉ</td> <td><input type="text" name="address" value="${sessionScope.address}" /></td> </tr> <tr> <td>Điện thoại</td> <td><input type="text" name="phone" value="${sessionScope.phone}"/></td> </tr> <tr> <td>Ghi chú</td> <td><textarea name="note"></textarea></td> <tr> <td> <button class="btn btn-primary">Đặt hàng</button> </td> </tr> </table> </form> </div> </div> |
Bước 8: Run ứng dụng và kiểm tra kết quả
- Màn hình giỏ hàng
- Màn hình login
Link tải source code
Video đang quay....
thay lời cảm ơn!
Các bài cũ hơn
- 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)
- [Java Web] Lọc, phân trang, tìm kiếm dữ liệu với SQL Server trong JSP Servlet (09:24 AM - 23/02/2024)
- [Java Web] Upload file-Tích hợp CKEditor vào JSP Servlet (03:38 PM - 20/02/2024)