基于javaweb+mysql的jsp+servlet网上书城+后台管理系统(java+jsp+servlert+mysql+ajax)
运行环境
Java≥8、MySQL≥5.7、Tomcat≥8
开发工具
eclipse/idea/myeclipse/sts等均可配置运行
适用
课程设计,大作业,毕业设计,项目练习,学习演示等
功能说明
基于javaweb+mysql的JSP+Servlet网上书城+后台管理系统(java+jsp+servlert+mysql+ajax)
一、项目简述(附带IW文档)
功能: 前台: * 用户模块 * 分类模块 * 图书模块 * 购物车模块 * 订单模块
后台: * 管理员模块 * 分类管理模块 * 图书管理模块 * 订单模块
二、项目运行
环境配置: Jdk1.8 + Tomcat8.5 + mysql + Eclispe (IntelliJ IDEA,Eclispe,MyEclispe,Sts 都支持)
项目技术: JSP + C3P0+ Servlert + html+ css + JavaScript + JQuery + Ajax + Fileupload等等。
public class LoginFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
/*
* 1. 获取session中的user
* 2. 判断是否为null
* > 如果为null:保存错误信息,转发到msg.jsp
* > 如果不为null:放行
*/
HttpServletRequest req = (HttpServletRequest) request;
Object user = req.getSession().getAttribute("sessionUser");
if(user == null) {
req.setAttribute("code", "error");//为了显示X图片
req.setAttribute("msg", "您还没有登录,不能访问本资源");
req.getRequestDispatcher("/jsps/msg.jsp").forward(req, response);
} else {
chain.doFilter(request, response);//放行
}
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
package cn.itcast.goods.admin.admin.web.servlet;
}
/*
* 5. 验证码校验
*/
String verifyCode = formUser.getVerifyCode();
String vcode = (String) session.getAttribute("vCode");
if(verifyCode == null || verifyCode.trim().isEmpty()) {
errors.put("verifyCode", "验证码不能为空!");
} else if(!verifyCode.equalsIgnoreCase(vcode)) {
errors.put("verifyCode", "验证码错误!");
}
return errors;
}
/**
* 激活功能
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String activation(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 获取参数激活码
* 2. 用激活码调用service方法完成激活
* > service方法有可能抛出异常, 把异常信息拿来,保存到request中,转发到msg.jsp显示
* 3. 保存成功信息到request,转发到msg.jsp显示。
*/
String code = req.getParameter("activationCode");
try {
userService.activatioin(code);
req.setAttribute("code", "success");//通知msg.jsp显示对号
req.setAttribute("msg", "恭喜,激活成功,请马上登录!");
} catch (UserException e) {
// 说明service抛出了异常
req.setAttribute("msg", e.getMessage());
req.setAttribute("code", "error");//通知msg.jsp显示X
}
return "f:/jsps/msg.jsp";
}
/**
* 修改密码
* @param req
* @param resp
* 3. 把Category赋给Book
* 4. 调用service完成工作
* 5. 保存成功信息,转发到msg.jsp
*/
Map map = req.getParameterMap();
Book book = CommonUtils.toBean(map, Book.class);
Category category = CommonUtils.toBean(map, Category.class);
book.setCategory(category);
bookService.edit(book);
req.setAttribute("msg", "修改图书成功!");
return "f:/adminjsps/msg.jsp";
}
/**
* 加载图书
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String load(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 获取bid,得到Book对象,保存之
*/
String bid = req.getParameter("bid");
Book book = bookService.load(bid);
req.setAttribute("book", book);
/*
* 2. 获取所有一级分类,保存之
*/
req.setAttribute("parents", categoryService.findParents());
/*
* 3. 获取当前图书所属的一级分类下所有2级分类
*/
String pid = book.getCategory().getParent().getCid();
req.setAttribute("children", categoryService.findChildren(pid));
/*
* 4. 转发到desc.jsp显示
*/
* 校验订单状态
*/
int status = orderService.findStatus(oid);
if(status != 2) {
req.setAttribute("code", "error");
req.setAttribute("msg", "状态不对,不能发货!");
return "f:/adminjsps/msg.jsp";
}
orderService.updateStatus(oid, 3);//设置状态为取消!
req.setAttribute("code", "success");
req.setAttribute("msg", "您的订单已发货,请查看物流,马上确认吧!");
return "f:/adminjsps/msg.jsp";
}
}
package cn.itcast.goods.cart.web.servlet;
public class CartItemServlet extends BaseServlet {
private CartItemService cartItemService = new CartItemService();
/**
* 加载多个CartItem
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String loadCartItems(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 获取cartItemIds参数
*/
String cartItemIds = req.getParameter("cartItemIds");
double total = Double.parseDouble(req.getParameter("total"));
public class OrderServlet extends BaseServlet {
private OrderService orderService = new OrderService();
private CartItemService cartItemService = new CartItemService();
/**
* 获取当前页码
* @param req
* @return
*/
private int getPc(HttpServletRequest req) {
int pc = 1;
String param = req.getParameter("pc");
if(param != null && !param.trim().isEmpty()) {
try {
pc = Integer.parseInt(param);
} catch(RuntimeException e) {}
}
return pc;
}
/**
* 截取url,页面中的分页导航中需要使用它做为超链接的目标!
* @param req
* @return
*/
/*
* http://localhost:8080/goods/BookServlet?methed=findByCategory&cid=xxx&pc=3
* /goods/BookServlet + methed=findByCategory&cid=xxx&pc=3
*/
private String getUrl(HttpServletRequest req) {
String url = req.getRequestURI() + "?" + req.getQueryString();
/*
* 如果url中存在pc参数,截取掉,如果不存在那就不用截取。
*/
int index = url.lastIndexOf("&pc=");
if(index != -1) {
url = url.substring(0, index);
throws ServletException, IOException {
/*
* 1. 得到pc:如果页面传递,使用页面的,如果没传,pc=1
*/
int pc = getPc(req);
/*
* 2. 得到url:...
*/
String url = getUrl(req);
/*
* 4. 使用pc和cid调用service#findByCategory得到PageBean
*/
PageBean<Order> pb = orderService.findAll(pc);
/*
* 5. 给PageBean设置url,保存PageBean,转发到/jsps/book/list.jsp
*/
pb.setUrl(url);
req.setAttribute("pb", pb);
return "f:/adminjsps/admin/order/list.jsp";
}
/**
* 按状态查询
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String findByStatus(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 得到pc:如果页面传递,使用页面的,如果没传,pc=1
*/
int pc = getPc(req);
/*
* 2. 得到url:...
*/
String url = getUrl(req);
/*
* 3. 获取链接参数:status
*/
int status = Integer.parseInt(req.getParameter("status"));
/*
* 4. 使用pc和cid调用service#findByCategory得到PageBean
*/
PageBean<Order> pb = orderService.findByStatus(status, pc);
/*
* 5. 给PageBean设置url,保存PageBean,转发到/jsps/book/list.jsp
*/
pb.setUrl(url);
req.setAttribute("pb", pb);
return "f:/adminjsps/admin/order/list.jsp";
/*
* 4.2 把上传的图片保存起来
* > 获取文件名:截取之
* > 给文件添加前缀:使用uuid前缀,为也避免文件同名现象
* > 校验文件的扩展名:只能是jpg
* > 校验图片的尺寸
* > 指定图片的保存路径,这需要使用ServletContext#getRealPath()
* > 保存之
* > 把图片的路径设置给Book对象
*/
// 获取文件名
FileItem fileItem = fileItemList.get(1);//获取大图
String filename = fileItem.getName();
// 截取文件名,因为部分浏览器上传的绝对路径
int index = filename.lastIndexOf("\\");
if(index != -1) {
filename = filename.substring(index + 1);
}
// 给文件名添加uuid前缀,避免文件同名现象
filename = CommonUtils.uuid() + "_" + filename;
// 校验文件名称的扩展名
if(!filename.toLowerCase().endsWith(".jpg")) {
error("上传的图片扩展名必须是JPG", request, response);
return;
}
// 校验图片的尺寸
// 保存上传的图片,把图片new成图片对象:Image、Icon、ImageIcon、BufferedImage、ImageIO
/*
* 保存图片:
* 1. 获取真实路径
*/
String savepath = this.getServletContext().getRealPath("/book_img");
/*
* 2. 创建目标文件
*/
File destFile = new File(savepath, filename);
/*
* 3. 保存文件
*/
try {
fileItem.write(destFile);//它会把临时文件重定向到指定的路径,再删除临时文件
} catch (Exception e) {
throw new RuntimeException(e);
}
// 校验尺寸
// 1. 使用文件路径创建ImageIcon
ImageIcon icon = new ImageIcon(destFile.getAbsolutePath());
// 2. 通过ImageIcon得到Image对象
Image image = icon.getImage();
// 3. 获取宽高来进行校验
if(image.getWidth(null) > 350 || image.getHeight(null) > 350) {
error("您上传的图片尺寸超出了350*350!", request, response);
//destFile.delete();//删除图片
public String createOrder(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 获取所有购物车条目的id,查询之
*/
String cartItemIds = req.getParameter("cartItemIds");
List<CartItem> cartItemList = cartItemService.loadCartItems(cartItemIds);
if(cartItemList.size() == 0) {
req.setAttribute("code", "error");
req.setAttribute("msg", "您没有选择要购买的图书,不能下单!");
return "f:/jsps/msg.jsp";
}
/*
* 2. 创建Order
*/
Order order = new Order();
order.setOid(CommonUtils.uuid());//设置主键
order.setOrdertime(String.format("%tF %<tT", new Date()));//下单时间
order.setStatus(1);//设置状态,1表示未付款
order.setAddress(req.getParameter("address"));//设置收货地址
User owner = (User)req.getSession().getAttribute("sessionUser");
order.setOwner(owner);//设置订单所有者
BigDecimal total = new BigDecimal("0");
for(CartItem cartItem : cartItemList) {
total = total.add(new BigDecimal(cartItem.getSubtotal() + ""));
}
order.setTotal(total.doubleValue());//设置总计
/*
* 3. 创建List<OrderItem>
* 一个CartItem对应一个OrderItem
*/
List<OrderItem> orderItemList = new ArrayList<OrderItem>();
for(CartItem cartItem : cartItemList) {
OrderItem orderItem = new OrderItem();
orderItem.setOrderItemId(CommonUtils.uuid());//设置主键
orderItem.setQuantity(cartItem.getQuantity());
orderItem.setSubtotal(cartItem.getSubtotal());
orderItem.setBook(cartItem.getBook());
orderItem.setOrder(order);
orderItemList.add(orderItem);
}
package cn.itcast.goods.admin.category.web.servlet;
public class AdminCategoryServlet extends BaseServlet {
private CategoryService categoryService = new CategoryService();
private BookService bookService = new BookService();
/**
* 查询所有分类
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String findAll(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setAttribute("parents", categoryService.findAll());
return "f:/adminjsps/admin/category/list.jsp";
}
/**
* 添加一级分类
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String addParent(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
int pc = 1;
String param = req.getParameter("pc");
if(param != null && !param.trim().isEmpty()) {
try {
pc = Integer.parseInt(param);
} catch(RuntimeException e) {}
}
return pc;
}
/**
* 截取url,页面中的分页导航中需要使用它做为超链接的目标!
* @param req
* @return
*/
/*
* http://localhost:8080/goods/BookServlet?methed=findByCategory&cid=xxx&pc=3
* /goods/BookServlet + methed=findByCategory&cid=xxx&pc=3
*/
private String getUrl(HttpServletRequest req) {
String url = req.getRequestURI() + "?" + req.getQueryString();
/*
* 如果url中存在pc参数,截取掉,如果不存在那就不用截取。
*/
int index = url.lastIndexOf("&pc=");
if(index != -1) {
url = url.substring(0, index);
}
return url;
}
/**
* 按分类查
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String findByCategory(HttpServletRequest req, HttpServletResponse resp)
/**
* 获取当前页码
* @param req
* @return
*/
private int getPc(HttpServletRequest req) {
int pc = 1;
String param = req.getParameter("pc");
if(param != null && !param.trim().isEmpty()) {
try {
pc = Integer.parseInt(param);
} catch(RuntimeException e) {}
}
return pc;
}
/**
* 截取url,页面中的分页导航中需要使用它做为超链接的目标!
* @param req
* @return
*/
/*
* http://localhost:8080/goods/BookServlet?methed=findByCategory&cid=xxx&pc=3
* /goods/BookServlet + methed=findByCategory&cid=xxx&pc=3
*/
private String getUrl(HttpServletRequest req) {
String url = req.getRequestURI() + "?" + req.getQueryString();
/*
* 如果url中存在pc参数,截取掉,如果不存在那就不用截取。
*/
int index = url.lastIndexOf("&pc=");
if(index != -1) {
url = url.substring(0, index);
}
return url;
}
/**
* 查看所有订单
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String load(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 获取bid,得到Book对象,保存之
*/
String bid = req.getParameter("bid");
Book book = bookService.load(bid);
req.setAttribute("book", book);
/*
* 2. 获取所有一级分类,保存之
*/
req.setAttribute("parents", categoryService.findParents());
/*
* 3. 获取当前图书所属的一级分类下所有2级分类
*/
String pid = book.getCategory().getParent().getCid();
req.setAttribute("children", categoryService.findChildren(pid));
/*
* 4. 转发到desc.jsp显示
*/
return "f:/adminjsps/admin/book/desc.jsp";
}
/**
* 添加图书:第一步
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String addPre(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 获取所有一级分类,保存之
* 2. 转发到add.jsp,该页面会在下拉列表中显示所有一级分类
*/
List<Category> parents = categoryService.findParents();
req.setAttribute("parents", parents);
return "f:/adminjsps/admin/book/add.jsp";
}
public String ajaxFindChildren(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 获取pid
* 2. 通过pid查询出所有2级分类
*/
Order order = new Order();
order.setOid(CommonUtils.uuid());//设置主键
order.setOrdertime(String.format("%tF %<tT", new Date()));//下单时间
order.setStatus(1);//设置状态,1表示未付款
order.setAddress(req.getParameter("address"));//设置收货地址
User owner = (User)req.getSession().getAttribute("sessionUser");
order.setOwner(owner);//设置订单所有者
BigDecimal total = new BigDecimal("0");
for(CartItem cartItem : cartItemList) {
total = total.add(new BigDecimal(cartItem.getSubtotal() + ""));
}
order.setTotal(total.doubleValue());//设置总计
/*
* 3. 创建List<OrderItem>
* 一个CartItem对应一个OrderItem
*/
List<OrderItem> orderItemList = new ArrayList<OrderItem>();
for(CartItem cartItem : cartItemList) {
OrderItem orderItem = new OrderItem();
orderItem.setOrderItemId(CommonUtils.uuid());//设置主键
orderItem.setQuantity(cartItem.getQuantity());
orderItem.setSubtotal(cartItem.getSubtotal());
orderItem.setBook(cartItem.getBook());
orderItem.setOrder(order);
orderItemList.add(orderItem);
}
order.setOrderItemList(orderItemList);
/*
* 4. 调用service完成添加
*/
orderService.createOrder(order);
// 删除购物车条目
cartItemService.batchDelete(cartItemIds);
/*
* 5. 保存订单,转发到ordersucc.jsp
*/
req.setAttribute("order", order);
return "f:/jsps/order/ordersucc.jsp";
}
/**
* 我的订单
/*
* 4. 使用pc和cid调用service#findByCategory得到PageBean
*/
PageBean<Book> pb = bookService.findByAuthor(author, pc);
/*
* 5. 给PageBean设置url,保存PageBean,转发到/jsps/book/list.jsp
*/
pb.setUrl(url);
req.setAttribute("pb", pb);
return "f:/jsps/book/list.jsp";
}
/**
* 按出版社查询
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String findByPress(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 得到pc:如果页面传递,使用页面的,如果没传,pc=1
*/
int pc = getPc(req);
/*
* 2. 得到url:...
*/
String url = getUrl(req);
/*
* 3. 获取查询条件,本方法就是cid,即分类的id
*/
String press = req.getParameter("press");
/*
* 4. 使用pc和cid调用service#findByCategory得到PageBean
*/
PageBean<Book> pb = bookService.findByPress(press, pc);
/*
* 5. 给PageBean设置url,保存PageBean,转发到/jsps/book/list.jsp
*/
pb.setUrl(url);
req.setAttribute("pb", pb);
return "f:/jsps/book/list.jsp";
}
/**
* 按图名查
req.setAttribute("msg", "状态不对,不能发货!");
return "f:/adminjsps/msg.jsp";
}
orderService.updateStatus(oid, 3);//设置状态为取消!
req.setAttribute("code", "success");
req.setAttribute("msg", "您的订单已发货,请查看物流,马上确认吧!");
return "f:/adminjsps/msg.jsp";
}
}
package cn.itcast.goods.cart.web.servlet;
public class CartItemServlet extends BaseServlet {
private CartItemService cartItemService = new CartItemService();
/**
* 加载多个CartItem
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String loadCartItems(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 获取cartItemIds参数
*/
String cartItemIds = req.getParameter("cartItemIds");
double total = Double.parseDouble(req.getParameter("total"));
/*
* 1. 得到pc:如果页面传递,使用页面的,如果没传,pc=1
*/
int pc = getPc(req);
/*
* 2. 得到url:...
*/
String url = getUrl(req);
/*
* 3. 获取查询条件,本方法就是cid,即分类的id
*/
String author = req.getParameter("author");
/*
* 4. 使用pc和cid调用service#findByCategory得到PageBean
*/
PageBean<Book> pb = bookService.findByAuthor(author, pc);
/*
* 5. 给PageBean设置url,保存PageBean,转发到/jsps/book/list.jsp
*/
pb.setUrl(url);
req.setAttribute("pb", pb);
return "f:/jsps/book/list.jsp";
}
/**
* 按出版社查询
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String findByPress(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 得到pc:如果页面传递,使用页面的,如果没传,pc=1
*/
int pc = getPc(req);
/*
* 2. 得到url:...
*/
String url = getUrl(req);
/*
* 3. 获取查询条件,本方法就是cid,即分类的id
*/
String press = req.getParameter("press");
/*
* 4. 使用pc和cid调用service#findByCategory得到PageBean
*/
sb.append("&").append("p8_Url=").append(p8_Url);
sb.append("&").append("p9_SAF=").append(p9_SAF);
sb.append("&").append("pa_MP=").append(pa_MP);
sb.append("&").append("pd_FrpId=").append(pd_FrpId);
sb.append("&").append("pr_NeedResponse=").append(pr_NeedResponse);
sb.append("&").append("hmac=").append(hmac);
resp.sendRedirect(sb.toString());
return null;
}
/**
* 回馈方法
* 当支付成功时,易宝会访问这里
* 用两种方法访问:
* 1. 引导用户的浏览器重定向(如果用户关闭了浏览器,就不能访问这里了)
* 2. 易宝的服务器会使用点对点通讯的方法访问这个方法。(必须回馈success,不然易宝服务器会一直调用这个方法)
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String back(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 获取12个参数
*/
String p1_MerId = req.getParameter("p1_MerId");
String r0_Cmd = req.getParameter("r0_Cmd");
String r1_Code = req.getParameter("r1_Code");
String r2_TrxId = req.getParameter("r2_TrxId");
String r3_Amt = req.getParameter("r3_Amt");
String r4_Cur = req.getParameter("r4_Cur");
String r5_Pid = req.getParameter("r5_Pid");
String r6_Order = req.getParameter("r6_Order");
String r7_Uid = req.getParameter("r7_Uid");
String r8_MP = req.getParameter("r8_MP");
String r9_BType = req.getParameter("r9_BType");
String hmac = req.getParameter("hmac");
/*
* 2. 获取keyValue
*/
Properties props = new Properties();
throws ServletException, IOException {
req.getSession().invalidate();
return "r:/jsps/user/login.jsp";
}
/**
* 登录功能
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String login(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
/*
* 1. 封装表单数据到User
* 2. 校验表单数据
* 3. 使用service查询,得到User
* 4. 查看用户是否存在,如果不存在:
* * 保存错误信息:用户名或密码错误
* * 保存用户数据:为了回显
* * 转发到login.jsp
* 5. 如果存在,查看状态,如果状态为false:
* * 保存错误信息:您没有激活
* * 保存表单数据:为了回显
* * 转发到login.jsp
* 6. 登录成功:
* * 保存当前查询出的user到session中
* * 保存当前用户的名称到cookie中,注意中文需要编码处理。
*/
/*
* 1. 封装表单数据到user
*/
User formUser = CommonUtils.toBean(req.getParameterMap(), User.class);
/*
* 2. 校验
*/
Map<String,String> errors = validateLogin(formUser, req.getSession());
if(errors.size() > 0) {
req.setAttribute("form", formUser);
req.setAttribute("errors", errors);
return "f:/jsps/user/login.jsp";
}
/*
* 3. 调用userService#login()方法
*/
User user = userService.login(formUser);