BookShop项目 - 各模块功能
导读:各模块的开发逻辑架构
-
业务逻辑 对项目的各部分进行开发时,首要任务是明确该部分的业务逻辑。明确任务逻辑后,才可能对html文件、dao层、service层、controller层有正确的操作。 -
html文件 明确session作用域中有哪些参数可以调用,部分参数对应的pojo类中的属性情况如何,然后对html文件使用thymeleaf进行渲染 -
dao层 根据业务逻辑,首先对涉及到的数据表进行必要的CRUD工作,使用的参数为对应的pojo类 -
service层 实现主要的业务逻辑,并为pojo类中的自建类属性赋值。 -
controller层 ① 获取session中的对应参数或form表单中提交的参数,并创建service层实现业务时所需的参数, ② 后调用service层内的业务方法,实现该部分的业务逻辑, ③ 在session中保存需要的变量 ④ 并跳转至相应的组件或html文件上 -
对应的参数表
序号 | 项目功能复杂时,可详细罗列各参数及对应的属性情况 |
---|
session参数 | | form表单提交的参数 | |
一、登录页面
-
业务逻辑 tomcat的URL对应跳转到的时登陆页面,输入用户名和密码后,提交后,在t_user内查询是否有对应的数据: 如果用户名或密码错误,就重新返回登录页面, 如果用户名和密码正确,则跳转至book.do,加载图书列表 -
页面显示效果 -
html <body>
<div class="msg_cont">
<b></b>
<span class="errorMsg">请输入用户名和密码</span>
</div>
<div class="form">
<form th:action="@{/user.do}" method="post">
<input type="hidden" name="operate" value="login"/>
<label>用户名称:</label>
<input
class="itxt"
type="text"
placeholder="请输入用户名"
autocomplete="off"
tabindex="1"
name="uname"
value="lina"
id="username"
/>
<label>用户密码:</label>
<input
class="itxt"
type="password"
placeholder="请输入密码"
autocomplete="off"
tabindex="1"
name="pwd"
value="ok"
id="password"
/>
<input type="submit" value="登录" id="sub_btn" />
</form>
</div>
</body>
-
dao
public class UserDAOImpl extends BaseDAO<User> implements UserDAO {
@Override
public User getUser(Connection conn,String uname, String password) {
String sql = "select * from t_user where uname = ? and pwd = ?";
return super.singleCommonRetrieve(conn,sql,uname,password);
}
}
-
service public class UserServiceImpl implements UserService {
private UserDAO userDAO;
@Override
public User getUser(Connection conn, String uname, String password) {
return userDAO.getUser(conn,uname,password);
}
}
-
controller public class UserController {
private Connection conn = JdbcUtils.getConnection();
private UserService userService;
private CartItemService cartItemService;
public String login(String uname, String pwd, HttpSession session) {
User user = userService.getUser(conn,uname,pwd);
if (user != null) {
session.setAttribute("currUser",user);
return "redirect:book.do";
}
return "user/login";
}
}
二、主页面
-
业务逻辑 主页面的图书列列表部分,需要读取数据库中t_book表内的数据进行实时渲染 -
页面显示效果 -
html
<div class="topbar-right" th:if="${session.currUser==null}">
<a href="user/login.html" class="login">登录</a>
<a href="user/regist.html" class="register">注册</a>
<a href="cart/cart.html" class="cart iconfont icon-gouwuche">购物车
<div class="cart-num" >3</div></a>
<a href="manager/book_manager.html" class="admin">后台管理</a>
</div>
<div class="topbar-right" th:unless="${session.currUser==null}">
<span>欢迎你<b th:text="*{session.currUser.getUname()}">张总</b></span>
<a href="#" class="register">注销</a>
<a th:href="@{/cart.do}" class="cart iconfont icon-gouwuche" >购物车<div
class="cart-num" th:text="${session.currUser.cart.totalCount}">3</div></a>
<a href="./pages/manager/book_manager.html" class="admin">后台管理</a>
</div>
<div class="list-content">
<div class="list-item" th:each="book : ${session.bookList}" th:object="${book}">
<img th:src="@{|/static/uploads/*{bookImg}|}" alt="">
<p th:text="|书名:*{bookName}|">书名:活着</p>
<p th:text="|作者:*{author}|">作者:余华</p>
<p th:text="|价格:¥*{price}|">价格:¥66.6</p>
<p th:text="|销量:*{saleCount}|">销量:230</p>
<p th:text="|库存:*{bookCount}|">库存:1000</p>
<button th:onclick="|addCart(*{id})|">加入购物车</button>
</div>
</div>
-
dao public class BookDAOImpl extends BaseDAO<Book> implements BookDAO {
@Override
public List<Book> getBookList(Connection conn) {
String sql = "select * from t_book where bookStatus = 0";
List<Book> bookList = super.CommonRetrieve(conn, sql);
return super.CommonRetrieve(conn,sql);
}
}
-
service public class BookServiceImpl implements BookService {
private BookDAO bookDAO;
@Override
public List<Book> getBookList(Connection conn) {
return bookDAO.getBookList(conn);
}
}
-
controller public class BookController {
private Connection conn = JdbcUtils.getConnection();
private BookService bookService;
public String index(HttpSession session) {
List<Book> bookList = bookService.getBookList(conn);
session.setAttribute("bookList",bookList);
return "index";
}
}
三、加入购物车(图书下侧的按钮)
-
业务逻辑 点击图书后的"加入购物车"按钮,跳转到购物车页面 如果该图书已经在购物车中,就数量加1, 如果该图书不在购物车中,则在购物车中新增一列,并生成一条新的购物项cartItem -
页面显示效果 -
业务分析,新增一个pojo 由于购物车页面是由多条购物记录cart_item组成的,而且有“金额”、“商品总数量”、“总金额”等其它属性,且要分别罗列各条购物记录的详细信息,所以要新建一个pojo类,对应购物车页面。 对应购物车中每条购物记录后的金额,应该在CartItem类中新加一个count属性 public class Cart {
private Map<Integer,CartItem> cartItemMap;
private Integer totalBookCount;
private Double totalMoney;
public Cart() {}
public Map<Integer, CartItem> getCartItemMap() {
return cartItemMap;
}
public void setCartItemMap(Map<Integer, CartItem> cartItemMap) {
this.cartItemMap = cartItemMap;
}
public Integer getTotalBookCount() {
totalBookCount = 0 ;
if(cartItemMap!=null && cartItemMap.size()>0){
for (CartItem cartItem : cartItemMap.values()){
totalBookCount = totalBookCount + cartItem.getBuyCount() ;
}
}
return totalBookCount;
}
public Double getTotalMoney() {
totalMoney = 0.0;
if(cartItemMap!=null && cartItemMap.size()>0){
Set<Map.Entry<Integer, CartItem>> entries = cartItemMap.entrySet();
for(Map.Entry<Integer,CartItem> cartItemEntry : entries){
CartItem cartItem = cartItemEntry.getValue();
BigDecimal bigDecimalPrice = new BigDecimal("" + cartItem.getBook().getPrice());
BigDecimal bigDecimalBuyCount = new BigDecimal("" + cartItem.getBuyCount());
BigDecimal bigDecimalTotalMoney = bigDecimalBuyCount.multiply(bigDecimalPrice);
totalMoney = totalMoney + bigDecimalTotalMoney.doubleValue() ;
}
}
return totalMoney;
}
}
public class CartItem {
private Integer id;
private Book book;
private Integer buyCount;
private User userBean;
private Double bookMoney;
private Double count;
public CartItem() {}
public CartItem(Integer id) {
this.id = id;
}
public Double getCount() {
BigDecimal bigDecimalPrice = new BigDecimal("" + getBook().getPrice());
BigDecimal bigDecimalBuyCount = new BigDecimal("" + buyCount);
BigDecimal bigDecimalCount = bigDecimalBuyCount.multiply(bigDecimalPrice);
count = bigDecimalCount.doubleValue();
return count;
}
}
-
html <div class="w">
<tbody>
<tr th:each="cart:${session.currUser.cart.cartItemMap.values()}">
<td>
<img th:src="@{|/static/uploads/${cart.book.bookImg}|}" alt="" />
</td>
<td th:text="${cart.book.bookName}">活着</td>
<td>
<span class="count" th:onclick="|editCart(${cart.id},${cart.buyCount-1})|">-</span>
<input class="count-num" type="text" th:value="${cart.buyCount}" />
<span class="count" th:onclick="|editCart(${cart.id},${cart.buyCount+1})|">+</span>
</td>
<td th:text="${cart.book.price}">36.8</td>
<td th:text="${cart.count}">36.8</td>
<td><a href="">删除</a></td>
</tr>
</tbody>
</div>
<div class="footer-right">
<div>共<span th:text="${session.currUser.cart.totalBookCount}">3</span>件商品</div>
<div class="total-price">总金额<span th:text="${session.currUser.cart.totalMoney}">99.9</span>元</div>
<a class="pay" th:href="@{/order.do?operate=checkout}">去结账</a>
</div>
-
dao public class CartItemImpl extends BaseDAO<CartItem> implements CartItemDAO {
@Override
public List<CartItem> getCartList(Connection conn, User user) {
String sql = "select * from t_cart_item where userBean = ?";
List<CartItem> cartItems = super.CommonRetrieve(conn, sql, user.getId());
return super.CommonRetrieve(conn,sql,user.getId());
}
@Override
public void addCartByBook(Connection conn, Book book,User user) {
String sql = "insert into t_cart_item values(0,?,1,?)";
super.update(conn,sql,book.getId(),user.getId());
}
@Override
public void updateCartByBook(Connection conn, Book book,CartItem cartItem) {
String sql = "update t_cart_item set buyCount = ? where book = ?";
super.update(conn,sql,cartItem.getBuyCount()+1,book.getId());
}
}
-
service public class CartItemServiceImpl implements CartItemService {
private CartItemDAO cartItemDAO;
private BookService bookService;
@Override
public List<CartItem> getCartItemList(Connection conn,User user) {
List<CartItem> cartList = cartItemDAO.getCartList(conn, user);
for (CartItem cartItem : cartList) {
Book book = bookService.getBook(conn, cartItem.getBook().getId());
cartItem.setBook(book);
}
return cartList;
}
@Override
public Cart getCart(Connection conn, User user) {
List<CartItem> cartItemList = getCartItemList(conn,user);
HashMap<Integer, CartItem> cartMap = new HashMap<>();
for (CartItem cartItem : cartItemList) {
cartMap.put(cartItem.getBook().getId(),cartItem);
}
Cart cart = new Cart();
cart.setCartItemMap(cartMap);
user.setCart(cart);
return cart;
}
@Override
public void addOrUpdateCartItem(Connection conn, Book book,User user) {
Cart cart = getCart(conn,user);
if (cart != null) {
Map<Integer, CartItem> cartItemMap = cart.getCartItemMap();
if (cartItemMap == null) {
cartItemMap = new HashMap<Integer,CartItem>();
}
if (cartItemMap.containsKey(book.getId())) {
CartItem cartItem = cartItemMap.get(book.getId());
cartItemDAO.updateCartByBook(conn,book,cartItem);
} else {
cartItemDAO.addCartByBook(conn,book,user);
}
} else {
cartItemDAO.addCartByBook(conn,book,user);
}
}
}
-
controller public class CartController {
private Connection conn = JdbcUtils.getConnection();
private CartItemService cartItemService;
public String index(HttpSession session){
User user = (User)session.getAttribute("currUser");
Cart cart = cartItemService.getCart(conn, user);
user.setCart(cart);
session.setAttribute("currUser",user);
return "/cart/cart";
}
public String addCart(Integer bookId, HttpSession session) {
User user = (User)session.getAttribute("currUser");
cartItemService.addOrUpdateCartItem(conn,new Book(bookId),user);
return "redirect:cart.do";
}
}
四、去结算至我的订单
-
业务逻辑 点击购物车页面的去结算按钮,直接生成一个新的订单,且生成多个对应的订单详情,插入数据库中对应的表中,并跳转至我的订单页面,展示最新的订单 一个购物项cartItem对应一条订单详情orderItem 一个购物车cart结算一次对应一个订单order 一个订单order对应多个订单详情orderItem -
页面效果 -
html <tbody>
<tr th:each="order : ${session.orderList}">
<td th:text="${order.orderNo}">12354456895</td>
<td th:text="${order.orderDate}">2015.04.23</td>
<td th:text="${order.orderMoney}">90.00</td>
<td th:text="${order.totalBookCount}">88</td>
<td><a href="" class="send">等待发货</a></td>
<td><a href="">查看详情</a></td>
</tr>
</tbody>
-
dao
public class OrderDAOImpl extends BaseDAO<Order> implements OrderDAO {
@Override
public Integer addOrder(Connection conn, Order order) {
String sql = "insert into t_order values(0,?,?,?,?,0,?)";
return super.update(conn,sql,order.getOrderNo(),order.getOrderDate(),order.getOrderUser().getId(),
order.getOrderMoney(),order.getTotalBookCount());
}
@Override
public List<Order> getOrder(Connection conn, User user) {
String sql = "select * from t_order where orderUser = ?";
return super.CommonRetrieve(conn,sql,user.getId());
}
}
public class OrderItemDAOImpl extends BaseDAO<OrderItem> implements OrderItemDAO {
@Override
public void addOrderItem(Connection conn, OrderItem orderItem) {
String sql = "insert into t_order_item values(0,?,?,?)";
super.CommonRetrieve(conn,sql,orderItem.getBook().getId(),orderItem.getBuyCount(),
orderItem.getOrderBean().getId());
}
}
-
service public class OrderServiceImpl implements OrderService {
private OrderDAO orderDAO;
private OrderItemDAO orderItemDAO;
private CartItemDAO cartItemDAO;
@Override
public void addOrder(Connection conn, Order order) {
Integer orderId = orderDAO.addOrder(conn, order);
User user = order.getOrderUser();
for (CartItem cartItem : user.getCart().getCartItemMap().values()) {
OrderItem orderItem = new OrderItem();
orderItem.setBook(cartItem.getBook());
orderItem.setBuyCount(cartItem.getBuyCount());
orderItem.setOrderBean(new Order(orderId));
orderItemDAO.addOrderItem(conn,orderItem);
}
for (CartItem cartItem : user.getCart().getCartItemMap().values()) {
cartItemDAO.deleteCartItem(conn,cartItem);
}
}
@Override
public List<Order> getOrder(Connection conn,User user) {
return orderDAO.getOrder(conn,user);
}
}
-
controller public class OrderController {
private Connection conn = JdbcUtils.getConnection();
private OrderService orderService;
public String index(HttpSession session) {
User user = (User)session.getAttribute("currUser");
List<Order> orderList = orderService.getOrder(conn, user);
session.setAttribute("orderList",orderList);
return "/order/order";
}
public String checkout(HttpSession session) {
Order order = new Order();
Date date = new Date();
LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfYear();
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();
order.setOrderNo(UUID.randomUUID()+"_"+year+month+day+hour+minute+second);
order.setOrderDate(date);
User user = (User)session.getAttribute("currUser");
order.setOrderUser(user);
order.setOrderMoney(user.getCart().getTotalMoney());
order.setTotalBookCount(user.getCart().getTotalBookCount());
order.setOrderStatus(0);
orderService.addOrder(conn,order);
return "redirect:order.do";
}
}
五、session过滤器
-
业务逻辑 在多个html页面中,都会使用到thymeleaf进行渲染,如果session中的值不存在,则会引发页面显示错误,故需要添加session过滤器,保证session在没有值的情况下可靠跳转至登录页面 -
新建一个过滤器
@WebFilter(urlPatterns = {"*.do","*.html"},
initParams = {
@WebInitParam(name = "bai",
value = "/bookshop/page.do?operate=page&page=user/login,/bookshop/user.do?null")
}
)
public class SessionFilter implements Filter {
List<String> baiList = null;
@Override
public void init(FilterConfig config) throws ServletException {
String baiStr = config.getInitParameter("bai");
String[] baiArr = baiStr.split(",");
baiList = Arrays.asList(baiArr);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
System.out.println("request.getRequestURI = " + request.getRequestURI());
System.out.println("request.getRequestURL = " + request.getRequestURL());
System.out.println("request.getQueryString = " + request.getQueryString());
String uri = request.getRequestURI();
String query = request.getQueryString();
String str = uri + "?" + query;
if (baiList.contains(str)) {
filterChain.doFilter(request,response);
} else {
HttpSession session = request.getSession();
Object currUserObj = session.getAttribute("currUser");
if (currUserObj == null) {
response.sendRedirect("page.do?operate=page&page=user/login");
} else {
filterChain.doFilter(request,response);
}
}
}
@Override
public void destroy() {
}
}
六、注册页面(验证码技术:kaptcha.jar)
-
业务逻辑 注册页面涉及到验证码(参考kaptcha的相关知识点),如果验证码不正确,就要重新回到注册页面。如果验证码正确,就将注册好的信息插入数据库中的t_user表,并跳转至登录页面 -
页面效果 -
regist.html文件 在input标签中要有name,否则提交之后获取到的是null值 <form th:action="@{/user.do}" method="post">
<input type="hidden" name="operate" value="regist">
<div class="form-item">
<div>
<label>用户名称:</label>
<input type="text" placeholder="请输入用户名" name="uname" value="宝2022" />
</div>
<span class="errMess" >用户名应为6~16位数组和字母组成</span>
</div>
<div class="form-item">
<div>
<label>用户密码:</label>
<input type="password" placeholder="请输入密码" name="pwd" value="ok"/>
</div>
<span class="errMess">密码的长度至少为8位</span>
</div>
<div class="form-item">
<div>
<label>确认密码:</label>
<input type="password" placeholder="请输入确认密码" />
</div>
<span class="errMess">密码两次输入不一致</span>
</div>
<div class="form-item">
<div>
<label>用户邮箱:</label>
<input type="text" placeholder="请输入邮箱" name="email" value="bao@163.com"/>
</div>
<span class="errMess">请输入正确的邮箱格式</span>
</div>
<div class="form-item">
<div>
<label>验证码:</label>
<div class="verify">
<input type="text" placeholder="" name="verifyCode"/>
<img th:src="@{/kaptcha.jpg}" alt="" />
</div>
</div>
<span class="errMess">请输入正确的验证码</span>
</div>
<button class="btn">注册</button>
</form>
-
dao public class UserDAOImpl extends BaseDAO<User> implements UserDAO {
@Override
public void addUser(Connection conn, User user) {
String sql = "insert into t_user values(0,?,?,?,0)";
super.update(conn,sql,user.getUname(),user.getPwd(), user.getEmail());
}
}
-
service public class UserServiceImpl implements UserService {
private UserDAO userDAO;
@Override
public void addUser(Connection conn, User user) {
userDAO.addUser(conn,user);
}
}
-
controller
public class UserController {
private Connection conn = JdbcUtils.getConnection();
private UserService userService;
public String regist(String uname,String pwd,String email,String verifyCode, HttpSession session) {
Object verifyCodeObj = (String)session.getAttribute("KAPTCHA_SESSION_KEY");
if (verifyCodeObj == null || !verifyCode.equals(verifyCodeObj)) {
return "user/regist";
} else {
if (verifyCode.equals(verifyCodeObj)) {
userService.addUser(conn,new User(uname,pwd,email));
return "user/login";
}
}
return "user/login";
}
}
七、注册页面输入规范检测(正则表达式)
-
业务逻辑 利用js中的正则表达式(Regular Express)对用户名、密码、邮箱的输入格式进行规范,不符合规范的输入会被提示,且不能提交至数据库 -
页面效果 -
html <!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<script language="JavaScript" th:src="@{/static/script/regist.js}"></script>
</head>
<body>
<h1>注册尚硅谷会员</h1>
<form th:action="@{/user.do}" method="post" onsubmit="return preRegist() ;">
<input type="hidden" name="operate" value="regist"/>
<div class="form-item">
<div>
<label>用户名称:</label>
<input id="unameTxt" type="text" placeholder="请输入用户名" name="uname" value="h2022" />
</div>
<span id="unameSpan" class="errMess" >用户名应为6~16位数组和字母组成</span>
</div>
<div class="form-item">
<div>
<label>用户密码:</label>
<input id="pwdTxt" type="password" placeholder="请输入密码" name="pwd" value="ok"/>
</div>
<span id="pwdSpan" class="errMess">密码的长度至少为8位</span>
</div>
<div class="form-item">
<div>
<label>确认密码:</label>
<input id="pwdTxt1" type="password" placeholder="请输入确认密码" name="pwd1" value="ok"/>
</div>
<span id="pwdSpan1" class="errMess">密码两次输入不一致</span>
</div>
<div class="form-item">
<div>
<label>用户邮箱:</label>
<input id="emailTxt" type="text" placeholder="请输入邮箱" name="email" value="bao@163.com"/>
</div>
<span id="emailSpan" class="errMess">请输入正确的邮箱格式</span>
</div>
<div class="form-item">
<div>
<label>验证码:</label>
<div class="verify">
<input type="text" placeholder="" name="verifyCode"/>
<img th:src="@{/kaptcha.jpg}" alt="" />
</div>
</div>
<span class="errMess">请输入正确的验证码</span>
</div>
<button class="btn">注册</button>
</form>
</body>
</html>
-
js function $(id){
return document.getElementById(id);
}
function preRegist(){
var unameReg = /[0-9a-zA-Z]{6,16}/;
var unameTxt = $("unameTxt");
var uname = unameTxt.value ;
var unameSpan = $("unameSpan");
if(!unameReg.test(uname)){
unameSpan.style.visibility="visible";
return false ;
}else{
unameSpan.style.visibility="hidden";
}
var pwdReg = /\w{8,}/g;
var pwdTxt = $("pwdTxt");
var pwdSpan = $("pwdSpan");
var pwd = pwdTxt.value;
if (!pwdReg.test(pwd)) {
pwdSpan.style.visibility="visible";
return false;
} else {
pwdSpan.style.visibility="hidden";
}
if ($("pwdTxt1").value!=$("pwdTxt").value) {
$("pwdSpan1").style.visibility="visible";
return false;
} else {
$("pwdSpan1").style.visibility="hidden";
}
var emailReg = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
var emailTxt = $("emailTxt");
var emailSpan = $("emailSpan");
var email = emailTxt.value;
if (!emailReg.test(email)) {
emailSpan.style.visibility="visible";
return false;
} else {
emailSpan.style.visibility="hidden";
}
return true;
}
八、注册页面用户名的监测(Ajax异步请求)
-
业务逻辑 使用Ajax异步请求技术,对页面进行局部刷新,监测用户名是否可以注册,如果在t_user内由该名称,则不可以注册。 -
页面效果 -
使用浏览器调试程序 -
html <div>
<label>用户名称:</label>
<input id="unameTxt" type="text" placeholder="请输入用户名" name="uname"
value="h2022" onblur="ckUname(this.value)"/>
</div>
-
js
var xmlHttpRequest;
function createXMLHttpRequest() {
if (window.XMLHttpRequest) {
xmlHttpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}
}
}
function ckUname(uname) {
createXMLHttpRequest();
var url = "user.do?operate=ckUname&uname="+uname;
xmlHttpRequest.open("GET",url,true);
xmlHttpRequest.onreadystatechange = ckUnameCB;
xmlHttpRequest.send();
}
function ckUnameCB() {
if (xmlHttpRequest.readyState==4 && xmlHttpRequest.status==200) {
alert(xmlHttpRequest.responseText);
if (xmlHttpRequest.responseText == "{'uname':'1'}") {
alert("用户可以注册");
} else {
alert("用户已存在");
}
}
}
-
dao public class UserDAOImpl extends BaseDAO<User> implements UserDAO {
@Override
public User getUser(Connection conn, String uname) {
String sql = "select * from t_user where uname = ?";
return super.singleCommonRetrieve(conn,sql,uname);
}
}
-
service public class UserServiceImpl implements UserService {
private UserDAO userDAO;
@Override
public User getUser(Connection conn, String uname) {
return userDAO.getUser(conn,uname);
}
}
-
controller public class UserController {
private Connection conn = JdbcUtils.getConnection();
private UserService userService;
public String ckUname(String uname) {
User user = userService.getUser(conn,uname);
if (user == null) {
return "json:{'uname':'1'}";
} else {
return "json:{'uname':'0'}";
}
}
}
-
servlet
if (retrunStr.startsWith("redirect:")) {
String redirectStr = retrunStr.substring("redirect:".length());
resp.sendRedirect(redirectStr);
} else if (retrunStr.startsWith("json:")) {
String jsonStr = retrunStr.substring("json:".length());
PrintWriter out = resp.getWriter();
out.print(jsonStr);
out.flush();
}else {
super.processTemplate(retrunStr,req,resp);
}
九、购物车功能改造(Vue+Axios)
-
业务逻辑 不再通过session来传递数据,改用Vue+Axios在前后端之间传输JSON数据 -
注意 thymeleaf会自动解析pojo类中的get方法 Axios进行的时前后端分离,value表达式获取的只是服务端响应的JSON数据 -
前端 html <!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" th:href="@{/static/css/minireset.css}" />
<link rel="stylesheet" th:href="@{/static/css/common.css}" />
<link rel="stylesheet" th:href="@{/static/css/cart.css}" />
<script language="JavaScript" th:src="@{/static/script/vue.js}"></script>
<script language="JavaScript" th:src="@{/static/script/axios.min.js}"></script>
<script language="JavaScript" th:src="@{/static/script/edit.js}"></script>
<base th:href="@{/}"/>
</head>
<body>
<div class="list" id="cart_div">
<div class="w">
<table>
<thead>
<tr>
<th>图片</th>
<th>商品名称</th>
<th>数量</th>
<th>单价</th>
<th>金额</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="cartItem in cart.cartItemMap" >
<td>
<img v-bind:src="'static/uploads/'+cartItem.book.bookImg" alt="" />
</td>
<td >{{cartItem.book.bookName}}</td>
<td>
<span class="count" v-on:click="editCart(cartItem.id,cartItem.buyCount-1)">-</span>
<input class="count-num" type="text" v-bind:value="cartItem.buyCount" />
<span class="count" v-on:click="editCart(cartItem.id,cartItem.buyCount+1)">+</span>
</td>
<td>{{cartItem.book.price}}</td>
<td>{{cartItem.count}}</td>
<td><a href="">删除</a></td>
</tr>
</tbody>
</table>
<div class="footer">
<div class="footer-left">
<a href="#" class="clear-cart">清空购物车</a>
<a href="#">继续购物</a>
</div>
<div class="footer-right">
<div>共<span>{{cart.totalBookCount}}</span>件商品</div>
<div class="total-price">总金额<span>{{cart.totalMoney}}</span>元</div>
<a class="pay" th:href="@{/order.do?operate=checkout}">去结账</a>
</div>
</div>
</div>
</div>
</body>
</html>
js
window.onload=function (){
var vue = new Vue({
el:"#cart_div",
data:{
cart:{}
},
methods:{
getCart:function (){
axios({
method:"POST",
url:"cart.do",
params:{
operate:'cartConfig'
}
})
.then(function (value){
var cart = value.data;
vue.cart = cart;
})
.catch(function (reason){
});
},
editCart:function (cartId1,buyCount1){
axios({
method:"POST",
url:"cart.do",
params:{
operate:'editCart',
cartId:cartId1,
buyCount:buyCount1
}
})
.then(function (value){
vue.getCart();
})
.catch(function (reason){
});
}
},
mounted:function () {
this.getCart();
}
});
}
-
service public class CartItemServiceImpl implements CartItemService {
private CartItemDAO cartItemDAO;
private BookService bookService;
@Override
public List<CartItem> getCartItemList(Connection conn,User user) {
List<CartItem> cartList = cartItemDAO.getCartList(conn, user);
for (CartItem cartItem : cartList) {
Book book = bookService.getBook(conn, cartItem.getBook().getId());
cartItem.setBook(book);
cartItem.getCount();
}
return cartList;
}
@Override
public Cart getCart(Connection conn, User user) {
List<CartItem> cartItemList = getCartItemList(conn,user);
HashMap<Integer, CartItem> cartMap = new HashMap<>();
for (CartItem cartItem : cartItemList) {
cartMap.put(cartItem.getBook().getId(),cartItem);
}
Cart cart = new Cart();
cart.setCartItemMap(cartMap);
cart.getTotalCount();
cart.getTotalBookCount();
cart.getTotalMoney();
user.setCart(cart);
return cart;
}
}
-
controller public class CartController {
private Connection conn = JdbcUtils.getConnection();
private CartItemService cartItemService;
public String editCart(Integer cartId,Integer buyCount) {
cartItemService.updateCartById(conn,buyCount,cartId);
return "json:";
}
public String cartConfig(HttpSession session) {
User user = (User)session.getAttribute("currUser");
Cart cart = cartItemService.getCart(conn, user);
Gson gson = new Gson();
String cartJsonStr = gson.toJson(cart);
return "json:"+cartJsonStr;
}
}
|