第一阶段:登录、注册的验证
1.使用jQuery技术对登录中的用户名、密码进行非空验证
思路:1.给提交按钮设置绑定点击事件
2.获取用户框中的值进行非空判断:如果为空进行输出语句+return false(使提交表单之后不再跳转页面)
代码如下:
1.表单提交按钮的输入框代码和登录注册的输入框代码:
<input type="submit" value="登录" id="sub_btn" />
<input class="itxt" type="text" placeholder="请输入用户名" autocomplete="off" tabindex="1" name="username" id="username" value="${empty param.username?"":param.username}"<!-- 用来设置数据的回显--> />
<input class="itxt" type="password" placeholder="请输入密码" autocomplete="off" tabindex="1" name="password" id="password"/>
2.给登录和密码设置点击事件
$(function () {
//给登录设置点击事件
$("#sub_btn").click(function () {
//获取用户输入框的值
var usernameval = $("#username").val();
if (usernameval==""){
alert("用户名不能为空");
return false;
}
//获取密码框的值
var pwdval = $("#password").val();
if (pwdval==""){
alert("密码框不能为空");
return false;
}
});
});
2.使用jQuery技术和正则表达式对注册中的用户名、密码、确认密码、邮箱进行格式验证,对验证码进行非空验证。
思路同第一步
代码如下:
$(function () {
//‘给提交按钮设置点击事件
$("#btn").click(function () {
//获取用户输入的内容
var userNameTest = $("#username").val();
//判断用户输入的正则表达式
var testuser=/^[a-z0-9_-]{3,16}$/;
//进行判断
var userpanduan = testuser.test(userNameTest);
if (!userpanduan){
$("#usermsg").text("请输入3到16位的字母、数字、下划线、减号组合的用户名");
return false;
}
//获取密码框的值
var passwordtest = $("#password").val();
//密码正则表达式
var testpassword=/^[a-z0-9_-]{6,18}$/;
//判断输入的密码是否符合
var passwordpanduan = testpassword.test(passwordtest);
if (!passwordpanduan){
// alert("密码输入格式不对");
$("#pwdmsg").text("密码输入格式不对");
return false;
}
//获取确认密码的文本框的值
var repwd = $("#repwd").val();
if (repwd!=passwordtest){
// alert("确认密码错误,请重新输入");
$("#repwdmsg").text("确认密码错误,请重新输入");
//设置确认密码框的内容为空
$("#repwd").val("");
return false;
}
//获取用户邮箱的值
var emailval = $("#email").val();
//设置邮箱的正则表达式
var emailzhengze=/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
//进行输入邮箱的判断
if (!emailzhengze.test(emailval)){
// alert("输入邮箱格式错误,请重新输入");
$("#emailmsg").text("输入邮箱的格式错误,请重新输入");
return false;
}
//获取验证码框内的值
var codeval = $("#code").val();
if (codeval==""){
alert("验证码不能为空");
return false;
}
});
第二阶段:实现登录、注册功能
小tip:软件中的三层架构:表示层<-->业务逻辑层<-->数据访问层
优势:结构清晰,耦合度降低,可维护性高,可扩展性高,利于开发任务同步进行,容易适应需求变化
书层的三层架构:
表示层:HTML、Servlet.接收用户的请求,调用业务逻辑层处理用户的请求,显示处理的结果
业务逻辑层:Service,调用数据访问层处理业务逻辑,采用面向接口编程的思想,先定义接口,再创建实现类
采用面向接口编程的思想,先定义接口,再创建实现类
思路:
1.创建baseServlet,在该Servlet里面从页面form表单获取执行方法名字的参数,利用反射的形式将这个方法执行,注意:这里获取到的参数名必须和在Servelt中要创建的方法名称一样。
2.创建userDao和它的实现类,在dao中写数据库然后Service层调用dao中的方法,最后传到Servlet执行判断
代码:
1.baseServlet的创建:
public class BaseServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//在第一次获取页面参数前设置乱码问题
request.setCharacterEncoding("UTF-8");
String methName = request.getParameter("way");
// if ("login".equals(request.getParameter("way"))){
// //证明在登录,调用当前类中的login方法
// login(request,response);
// }else if ("regist".equals(request.getParameter("way"))){
// //证明在注册,调用当前类中的regist方法
// regist(request,response);
// }
Method method = null;
try {
method = this.getClass().getDeclaredMethod(methName, HttpServletRequest.class, HttpServletResponse.class);
//设置访问权限
method.setAccessible(true);
//调用方法
method.invoke(this, request, response);
} catch (Exception e) {
//在baseDao往上抛异常的过程中,抛到servlet然后servlet再抛到baseServlet,通过baseservlet再往过滤器中抛异常
// e.printStackTrace();
throw new RuntimeException();
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
2.创建UserDao及其实现类
创建UserDao:
public interface UserDao {
/**
* 通过username,password向数据库中查询一条记录
* @param username 传入的username
* @param password 传入的password
* @return User对象:存在
* null:不存在
*/
User logincheck(String username,String password);
/**
* 通过username在数据库中查询出一条数据
* @param username 传入的username
* @return true:说明数据库中存在数据
* false:说明数据库中不存在数据
*/
boolean isExistUsername(String username);
/**
* 向数据库中添加数据
* @param username 传入的username
* @param password 传入的password
* @param email 传入的email
*/
void addUser(String username,String password,String email);
}
创建它的实现类UserDaoImpl:
public class UserDaoImpl extends BaseDao<User> implements UserDao {
@Override
public User logincheck(String username, String password) {
String sql="select id,username,password,email from users where username=? and password=?";
User user=getBean(sql,username,password);
return user;
}
@Override
public boolean isExistUsername(String username) {
//获取baseDao中获取一个对象的方法
String sql="select id,username,password,email from users where username=?";
User user=getBean(sql,username);
if (user!=null){
return true;
}else {
return false;
}
}
@Override
public void addUser(String username, String password, String email) {
String sql="insert into users(username,password,email) values(?,?,?)";
update(sql,username,password,email);
}
}
3.创建service及其实现类
创建UserService
public interface UserService {
//用于登录判断
User login(User user);
//用于注册判断
boolean regist(User user);
//用于添加数据
void addUser(User user);
}
创建它的实现类
public class UserServiceImpl implements UserService {
UserDao userDao=new UserDaoImpl();
@Override
public User login(User user) {
return userDao.logincheck(user.getUsername(),user.getPassword());
}
@Override
public boolean regist(User user) {
return userDao.isExistUsername(user.getUsername());
}
@Override
public void addUser(User user) {
userDao.addUser(user.getUsername(),user.getPassword(),user.getEmail());
}
}
4.创建Useservlet继承BaseServlet,通过BaseServlet的反射将Userservlet中的login和regist方法执行
@WebServlet(name = "UserServlet",urlPatterns = "/UserServlet")
public class UserServlet extends BaseServlet {
protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建userservice的实现类的对象
UserService userService=new UserServiceImpl();
//获取从页面传来的username,password
String username=request.getParameter("username");
String password=request.getParameter("password");
//封装进User
User user=new User(null,username,password,null);
//调用userservice实现类的重写方法得到User对象进行判断
User loginuser=userService.login(user);
if (loginuser!=null){
//查询到数据,用户名密码正确
//创建session
HttpSession session = request.getSession();
//将loginuser添加到session域中
session.setAttribute("user",loginuser);
// ,重定向到成功页面
response.sendRedirect(request.getContextPath()+"/pages/user/login_success.jsp");
}else {
//设置域
request.setAttribute("msg","密码错误请重新输入");
//未查询到数据,转发到登录页面
request.getRequestDispatcher("/pages/user/login.jsp").forward(request,response);
}
}
protected void regist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取userservice的实现类对象
UserService userService= new UserServiceImpl();
//获取页面传过来的username,password,email
String username=request.getParameter("username");
String password=request.getParameter("password");
String email=request.getParameter("email");
//获取输入框验证码的值
String inputcode = request.getParameter("code");
//获取session域中的验证码的值
HttpSession session = request.getSession();
String sessioncode = (String) session.getAttribute("code");
if (inputcode.equals(sessioncode)){
//验证码正确,清除session
session.removeAttribute("code");
//封装进User对象
User user=new User(null,username,password,email);
//调用Userservice实现类的方法获得对象进行判断
boolean isflag= userService.regist(user);
if (isflag){
//返回true:数据库中存在用户
//转发到regist.html页面
request.setAttribute("msg","已存在用户,请重新输入");
request.getRequestDispatcher("/pages/user/regist.jsp").forward(request,response);
}else {
//返回false:数据库中没有数据,进行添加操作
userService.addUser(user);
//注册成功重定向跳入regist_success.html页面
response.sendRedirect(request.getContextPath()+"/pages/user/regist_success.jsp");
}
}
else {
//验证码不正确
request.setAttribute("msg","验证码错误");
//请求转发到注册页面
request.getRequestDispatcher("/pages/user/regist.jsp").forward(request,response);
}
}
}
第三阶段:动态书城的开始及局部优化
思路:
代码:
动态获取base标签:
1.在WEB-INF下创建一个include目录,将base.jsp放入include目录中,包含base标签
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<base href="${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath}/">
2.在每个页面合适的地方使用静态包含
<%@include file="/WEB-INF/include/base.jsp"%>
显示错误消息并表单回显:
登录:
1.在UserServlet中的login方法中如果登录失败设置错误消息保存到request域中
//设置域
request.setAttribute("msg","密码错误请重新输入");
//未查询到数据,转发到登录页面
request.getRequestDispatcher("/pages/user/login.jsp").forward(request,response);
2.并在login.jsp页面从request域中获取到数据显示在页面上:
<div class="msg_cont">
<b></b>
<span class="errorMsg">${empty requestScope.msg?"请输入用户名和密码":requestScope.msg}</span>
</div>
3.登录失败之后将用户名回显在表单中,用户input中设置属性:
value="${empty param.username?"":param.username}"
注册:
1.在UserServlet中的regist方法如果数据库中存在用户,设置request域将错误的信息保存在域中
if (isflag){
//返回true:数据库中存在用户
//转发到regist.html页面
request.setAttribute("msg","已存在用户,请重新输入");
request.getRequestDispatcher("/pages/user/regist.jsp").forward(request,response);
}
2.错误信息的显示:
</div>
<span class="errMess" id="usermsg">${empty requestScope.msg?"请输入用户名":requestScope.msg}</span>
</div>
第四阶段:图书的增删改查
思路:1.创建Book的javaBean
2.创建dao,service',servlet及其相关方法
3.实现查询所有的功能
查询所有流程图
(1)编写dao及其实现类
dao:
/**
* 在数据库查询出所有的图书列表
* @return 返回一个list集合
*/
List<Books> selectAllBooks();
dao实现类:
@Override
public List<Books> selectAllBooks() {
String sql="select id,title,author,price,sales,stock,img_path imgPath from books";
List<Books> beanList = getBeanList(sql);
return beanList;
}
(2)编写service及其实现类
service:
List<Books> selectAllBooks();
service实现类:
@Override
public List<Books> selectAllBooks() {
List<Books> books = bookDao.selectAllBooks();
return books;
}
(3)编写servlet
protected void selectAllBook(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//调用方法获得books集合
List<Books> books = bookService.selectAllBooks();
//将books集合存放在request域当中
request.setAttribute("books",books);
//请求转发到book_manager.jsp页面
request.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(request,response);
}
最后在book_manager.jsp页面中使用jstl和el表达式进行查询
4.实现添加的功能
添加图书的流程
(1)编写dao及其实现类的代码
dao:
/**
* 向数据库中添加图书
* @param books
*/
void addBooks(Books books);
实现类中的代码:
@Override
public void addBooks(Books books) {
String sql="insert into books(title,author,price,sales,stock,img_path) values(?,?,?,?,?,?)";
update(sql, books.getTitle(), books.getAuthor(), books.getPrice(), books.getSales(), books.getStock(),books.getImgPath());
}
(2)编写service及其实现类的代码
service:
void addBooks(Books books);
service实现类中的代码:
@Override
public void addBooks(Books books) {
bookDao.addBooks(books);
}
(3)编写servlet中的代码
protected void addBooks(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取页面传来的参数
String bookName = request.getParameter("bookName");
String bookPrice = request.getParameter("bookPrice");
String bookAuthor = request.getParameter("bookAuthor");
String bookSales = request.getParameter("bookSales");
String bookStock = request.getParameter("bookStock");
//创建Books的实例
Books books = new Books(null,bookName,bookAuthor,Double.parseDouble(bookPrice),Integer.parseInt(bookSales),Integer.parseInt(bookStock));
//调用service的增加图书的方法
bookService.addBooks(books);
//添加图书之后跳转查询所有显示所有的图书
response.sendRedirect(request.getContextPath()+"/BookServlet?way=selectAllBook");
}
5.实现删除的功能
删除功能流程图
(1)编写dao及其实现类
dao:
/**
* 根据id删除图书
* @param id
*/
void deleteBookById(int id);
dao的实现类:
@Override
public void deleteBookById(int id) {
String sql="delete from books where id=?";
update(sql,id);
}
(2)编写service及其实现类
service:
void deleteBookById(int id);
实现类:
@Override
public void deleteBookById(int id) {
bookDao.deleteBookById(id);
}
(3)编写servlet
protected void deleteById(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取页面参数值id
String id = request.getParameter("id");
//调用service的删除方法
bookService.deleteBookById(Integer.parseInt(id));
//跳转查询所有页面
response.sendRedirect(request.getContextPath()+"/BookServlet?way=getBooks");
}
最终跳转到查询所有界面
6.实现修改的功能
修改流程图:
修改的步骤如图所示:首先通过id查询获取要修改的图书的信息传到修改页面,然后通过修改图书的操作重定向到查询所有的界面
(1)编写通过id查询数据的dao实现类和service实现类
dao实现类:
@Override
public Books selectBookById(int id) {
String sql="select id,title,author,price,sales,stock,img_path imgPath from books where id=?";
Books books = getBean(sql, id);
return books;
}
service实现类:
@Override
public Books selectBookById(int id) {
Books books = bookDao.selectBookById(id);
return books;
}
(2)编写通过id查询图书数据的方法
protected void selectBookById(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//从页面获取id的参数值
String id = request.getParameter("id");
//调用service的查询方法
Books books = bookService.selectBookById(Integer.parseInt(id));
//添加到request域中
request.setAttribute("bookbyid",books);
//请求转发
request.getRequestDispatcher("/pages/manager/book_addandupdate.jsp").forward(request,response);
}
查询到数据之后转发到修改的页面,修改页面获取从dao中根据id查询的信息,然后将id值和其他参数值传入到修改的servlet中
(3)编写修改语句的dao实现类及其service实现类:
dao实现类:
@Override
public void updateBook(Books books) {
String sql="update books set title=?,author=?,price=?,sales=?,stock=? where id=?";
update(sql,books.getTitle(),books.getAuthor(),books.getPrice(),books.getSales(),books.getStock(),books.getId());
}
service实现类:
@Override
public void update(Books books) {
bookDao.updateBook(books);
}
(4)编写servlet中的修改的方法(和add(增加方法)的整合) (注:修改方法带有参数id,添加方法不带有参数id)
protected void addAndupdateBook(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//从页面获取的参数值
String id = request.getParameter("id");
String bookName = request.getParameter("bookName");
String bookPrice = request.getParameter("bookPrice");
String bookAuthor = request.getParameter("bookAuthor");
String bookSales = request.getParameter("bookSales");
String bookStock = request.getParameter("bookStock");
//判断是修改页面还是添加页面
if ("".equals(id)){
//创建Books的实例
Books books = new Books(null,bookName,bookAuthor,Double.parseDouble(bookPrice),Integer.parseInt(bookSales),Integer.parseInt(bookStock));
//调用service的增加图书的方法
bookService.addBooks(books);
//添加图书之后跳转查询所有显示所有的图书
response.sendRedirect(request.getContextPath()+"/BookServlet?way=getBooks");
}else {
//创建Books的对象
Books books = new Books(Integer.parseInt(id),bookName,bookAuthor,Double.parseDouble(bookPrice),Integer.parseInt(bookSales),Integer.parseInt(bookStock));
//调用bookservice方法
bookService.update(books);
response.sendRedirect(request.getContextPath()+"/BookServlet?way=getBooks");
}
}
7.实现分页的功能
-
- 如果添加分页操作我们需要知道总页数、当前页码、总记录数等信息,但是List中并没有这些信息,所有我们需要创建一个类来封装分页的信息。
- 流程图
- (1).创建Page<T>类(javabean)
-
public class Page<T> { private List<T> list;//从数据库分页得来的一页数据 private static final int PAGE_SIZE=5;//每页显示的数据的数量 private int pageNo;//当前的页码数,由用户在页面传来 private int pageRecoder;//数据库中数据的总记录数 private int pageNum;//总页码数,通过计算得到 public Page(List<T> list, int pageNo, int pageRecoder, int pageNum) { this.list = list; this.pageNo = pageNo; this.pageRecoder = pageRecoder; this.pageNum = pageNum; } public Page() { } public List<T> getList() { return list; } public void setList(List<T> list) { this.list = list; } public static int getPageSize() { return PAGE_SIZE; } public int getPageNo() { //如果当前页码小于1,则返回1 if (pageNo<1){ return 1; //如果当前页码大于总页数,则返回总页数 }else if (pageNo>getPageNum()){ return getPageNum(); }else { //如果当前页码大于等于1,小于等于总页数,则返回当前页码 return pageNo; } } public void setPageNo(int pageNo) { this.pageNo = pageNo; } public int getPageRecoder() { return pageRecoder; } public void setPageRecoder(int pageRecoder) { this.pageRecoder = pageRecoder; } public int getPageNum() { if (pageRecoder%PAGE_SIZE==0){ return pageRecoder/PAGE_SIZE; }else{ return pageRecoder/PAGE_SIZE+1; } } @Override public String toString() { return "Page{" + "list=" + list + ", pageNo=" + pageNo + ", pageRecoder=" + pageRecoder + ", pageNum=" + pageNum + '}'; } }
(2).修改dao添加一个分页的方法:编写dao的实现类
-
-
@Override public Page<Books> getBooks(Page<Books> page) { String sql="select count(*) from books"; long count = (long)getCount(sql); page.setPageRecoder((int) count); String sql1="select id,title,author,price,sales,stock,img_path imgPath from books limit ?,?"; List<Books> beanList = getBeanList(sql1, (page.getPageNo()-1) * Page.getPageSize(), Page.getPageSize()); page.setList(beanList); return page; }
(3).修改service,编写service的实现类
-
-
@Override public Page<Books> getBooks(String pageNo) { Page<Books> page = new Page<>(); int defaultPage=1; try { defaultPage=Integer.parseInt(pageNo); } catch (Exception e) { e.printStackTrace(); } page.setPageNo(defaultPage); return bookDao.getBooks(page); }
(4).编写servlet
-
-
protected void getBooks(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //从页面获取参数 String pageNo = request.getParameter("pageNo"); //调用bookservice方法传入页码数的对象 Page<Books> pagebooks = bookService.getBooks(pageNo); //将books放到域对象中 request.setAttribute("page",pagebooks); //请求转发到显示图书页面 request.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(request,response); }
8.关于页码分页的问题
-
-
</div> <div class="list-footer"> <c:if test="${requestScope.page.pageNo>1}"> <div><a href="clientBookServlet?way=getPageAndPrice&pageNo=1&minPrice=${requestScope.minPrice}&maxPrice=${requestScope.maxPrice}">首页</a></div> <div><a href="clientBookServlet?way=getPageAndPrice&pageNo=${requestScope.page.pageNo-1}&minPrice=${requestScope.minPrice}&maxPrice=${requestScope.maxPrice}">上一页</a></div> </c:if> <%-- 需求:页码数量等于五 1.当总页码小于5时,begin值为1,end值为当前最大页码数 2.当总页码数超过5时 1)当当前页码<=3时,begin值为1,end值为5. 2)当当前页码>3时,begin值为当前页码值-2,end值为当前页码值+2 2.1)当end值>总页码时,end值为页码最大值 begin值为最大值-4 --%> <c:choose> <%--当总页码小于5时--%> <c:when test="${requestScope.page.pageNum<5}"> <%--begin的值为1,end值为当前的最大页码数--%> <c:set var="begin" value="1"></c:set> <c:set var="end" value="${requestScope.page.pageNum}"></c:set> </c:when> <%--当当前页码值小于三时--%> <c:when test="${requestScope.page.pageNo<=3}"> <%--begin值为1,end值为5--%> <c:set var="begin" value="1"></c:set> <c:set var="end" value="5"></c:set> </c:when> <%--当当前页码大于三时--%> <c:otherwise> <%--begin值为当前页码-2,end值为当前页码+2--%> <c:set var="begin" value="${requestScope.page.pageNo-2}"></c:set> <c:set var="end" value="${requestScope.page.pageNo+2}"></c:set> <%--当end值大于总页码值时,end值为页码最大值,begin值为页码最大值-4--%> <c:if test="${end>requestScope.page.pageNum}"> <c:set var="begin" value="${requestScope.page.pageNum-4}"></c:set> <c:set var="end" value="${requestScope.page.pageNum}"></c:set> </c:if> </c:otherwise> </c:choose> <ul> <c:forEach begin="${begin}" end="${end}" var="index"> <c:if test="${requestScope.page.pageNo==index}"> <li class="active"><a href="clientBookServlet?way=getPageAndPrice&pageNo=${index}&minPrice=${requestScope.minPrice}&maxPrice=${requestScope.maxPrice}">${index}</a></li> </c:if> <c:if test="${requestScope.page.pageNo!=index}"> <li><a href="clientBookServlet?way=getPageAndPrice&pageNo=${index}&minPrice=${requestScope.minPrice}&maxPrice=${requestScope.maxPrice}">${index}</a></li> </c:if> </c:forEach> </ul> <c:if test="${requestScope.page.pageNo<requestScope.page.pageNum}"> <div><a href="clientBookServlet?way=getPageAndPrice&pageNo=${requestScope.page.pageNum}&minPrice=${requestScope.minPrice}&maxPrice=${requestScope.maxPrice}">末页</a></div> <div><a href="clientBookServlet?way=getPageAndPrice&pageNo=${requestScope.page.pageNo+1}&minPrice=${requestScope.minPrice}&maxPrice=${requestScope.maxPrice}">下一页</a></div> </c:if> <span>共${requestScope.page.pageNum}页</span> <span>${requestScope.page.pageRecoder}条记录</span> <span>到第</span> <input type="text" id="yema" name="yema"/> <span>页</span> <button class="btn">确定</button> </div> </div> </div>
8.前台图书的显示
-
创建dao中的方法
-
@Override public Page<Books> getPageAndPrice(Page<Books> page, double defaultminPrice, double defaultmaxPrice) { String sql="select count(*) from books where price between ? and ?"; long count = (long)getCount(sql,defaultminPrice,defaultmaxPrice); page.setPageRecoder((int) count); String sql1="select id,title,author,price,sales,stock,img_path imgPath from books where price between ? and ? limit ?,?"; List<Books> beanList = getBeanList(sql1,defaultminPrice,defaultmaxPrice, (page.getPageNo()-1) * Page.getPageSize(), Page.getPageSize()); page.setList(beanList); return page; }
在service中获取dao中的方法
-
@Override public Page<Books> getPageAndPrice(String pageNo, String minPrice, String maxPrice) { Page<Books> page = new Page<>(); int defaultPage=1; double defaultminPrice=0; double defaultmaxPrice=Double.MAX_VALUE; try { defaultPage=Integer.parseInt(pageNo); } catch (Exception e) { e.printStackTrace(); } try { defaultminPrice=Double.parseDouble(minPrice); } catch (Exception e) { e.printStackTrace(); } try { defaultmaxPrice=Double.parseDouble(maxPrice); } catch (Exception e) { e.printStackTrace(); } if (defaultminPrice>defaultmaxPrice){ double temp=defaultminPrice; defaultminPrice=defaultmaxPrice; defaultmaxPrice=temp; } page.setPageNo(defaultPage); return bookDao.getPageAndPrice(page,defaultminPrice,defaultmaxPrice); }
创建servlet
-
protected void getPageAndPrice(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //从页面获取参数 String pageNo = request.getParameter("pageNo"); String minPrice = request.getParameter("minPrice"); String maxPrice = request.getParameter("maxPrice"); //调用bookservice方法传入页码数的对象 Page<Books> pagebooks = bookService.getPageAndPrice(pageNo,minPrice,maxPrice); //将pagebooks放到域对象中 request.setAttribute("page",pagebooks); //将最大值和最小值放到域中 request.setAttribute("minPrice",minPrice); request.setAttribute("maxPrice",maxPrice); //请求转发到显示图书页面 request.getRequestDispatcher("/pages/client/client.jsp").forward(request,response); }
第五阶段:登录,登出、验证码、购物车
-
登录:在第二阶段已经实现
-
登出:
-
protected void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //创建session域 HttpSession session = request.getSession(); //使session失效 session.invalidate(); //重定向到首页 response.sendRedirect(request.getContextPath()+"/index.jsp"); // //请求转发到首页 // request.getRequestDispatcher("/index.jsp").forward(request,response); }
验证码:
- 导入kaptcha-2.3.2.jar包之后
- 在web.xml文件中注册Servlet
-
<!--配置验证码的servlet--> <servlet> <servlet-name>KaptchaServlet</servlet-name> <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class> <!--配制session中的key值--> <init-param> <param-name>kaptcha.session.key</param-name> <param-value>code</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>KaptchaServlet</servlet-name> <url-pattern>/code</url-pattern> </servlet-mapping>
在session域中获取验证码,获取之后移除
-
//获取输入框验证码的值 String inputcode = request.getParameter("code"); //获取session域中的验证码的值 HttpSession session = request.getSession(); String sessioncode = (String) session.getAttribute("code"); //进行判断 if (inputcode.equals(sessioncode)){ //验证码正确,清除session session.removeAttribute("code"); //下面写要实现的需求 }
购物车:
- 购物车,购物项的理解
- 购物车模块的分析
- 创建购物项类
-
package com.atguigu.bean; import java.math.BigDecimal; public class CartItem { private Books books;//购物项中购买的图书 private double amount;//购物项中图书的金额小计,通过计算得到 private int count;//购物项中购买的图书的数量 public CartItem(Books books, double amount, int count) { this.books = books; this.amount = amount; this.count = count; } public CartItem() { } @Override public String toString() { return "CartItem{" + "books=" + books + ", amount=" + amount + ", count=" + count + '}'; } public Books getBooks() { return books; } public void setBooks(Books books) { this.books = books; } //图书的金额小计由图书的数量和单价计算得出 public double getAmount() { BigDecimal price = new BigDecimal(books.getPrice()+""); BigDecimal count = new BigDecimal(this.count+""); BigDecimal total = price.multiply(count); double v = total.doubleValue(); return v; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } }
- 创建购物车类
- 创建购物车类的同时,也创建其相关的方法
-
package com.atguigu.bean; import java.math.BigDecimal; import java.util.*; public class Cart { //String代表的是图书的id,CartItem代表的是图书项 private Map<String,CartItem> map=new HashMap<>(); private int totalCount; private double totalAmount; @Override public String toString() { return "Cart{" + "map=" + map + ", totalCount=" + totalCount + ", totalAmount=" + totalAmount + '}'; } public Cart(Map<String, CartItem> map, int totalCount, double totalAmount) { this.map = map; this.totalCount = totalCount; this.totalAmount = totalAmount; } public Cart() { } public Map<String, CartItem> getMap() { return map; } public void setMap(Map<String, CartItem> map) { this.map = map; } //得到每一个图书项 public List<CartItem> getCartItem(){ Collection<CartItem> values = map.values(); return new ArrayList<>(values); } //获取图书的总数量 public int getTotalCount() { //得到图书项 List<CartItem> cartItem = getCartItem(); int totalCount=0; //遍历图书项 for (CartItem c:cartItem){ totalCount+=c.getCount(); } return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public void setTotalAmount(double totalAmount) { this.totalAmount = totalAmount; } //获取金额小计的总金额 public double getTotalAmount() { //获取图书项 List<CartItem> cartItem = getCartItem(); // double totalAmount=0; BigDecimal totalAmount = new BigDecimal("0"); for (CartItem c:cartItem){ BigDecimal amout = new BigDecimal(c.getAmount() + ""); totalAmount = totalAmount.add(amout); } return totalAmount.doubleValue(); } //删除图书项 public void deleteCartItem(String bookId){ map.remove(bookId); } //清空图书项 public void clearCartItem(){ map.clear(); } //更新图书 public void updateCartItem(String bookId,String bookCount){ //通过bookId得到图书项 CartItem cartItem = map.get(bookId); int count=0; try { count=Integer.parseInt(bookCount); if (count<0){ count=1; } } catch (NumberFormatException e) { e.printStackTrace(); } cartItem.setCount(count); } //添加图书 public void addCartItem(Books books){ //根据图书的id从购物车中查询对应的购物项 CartItem cartItem = map.get(books.getId() + ""); //判断cartItem是否为null if(cartItem == null){ //证明购物车中还没有该购物项 //创建该图书对应的购物项 cartItem = new CartItem(); //将book设置到购物项中 cartItem.setBooks(books); //设置该购物项中图书的数量为1 cartItem.setCount(1); //将该购物项添加到购物车中 map.put(books.getId()+"",cartItem); }else{ //证明购物车中已经有该购物项,此时只需要将该购物项中图书的数量加1即可 //获取当前购物项中图书的数量 int count = (int) cartItem.getCount(); //将数量加1 cartItem.setCount(count+1); } } }
创建servlet
-
package com.atguigu.servlet; import com.atguigu.bean.Books; import com.atguigu.bean.Cart; import com.atguigu.bean.CartItem; import com.atguigu.service.BookService; import com.atguigu.service.Impl.BookServiceImpl; import com.google.gson.Gson; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.HashMap; import java.util.Map; @WebServlet(name = "CartServlet",urlPatterns = "/cartServlet") public class CartServlet extends BaseServlet { BookService bookService=new BookServiceImpl(); protected void changeinput(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取id值 String id = request.getParameter("id"); //获取bookCount String bookCount = request.getParameter("bookCount"); //从session域中获取cart HttpSession session = request.getSession(); Cart cart = (Cart) session.getAttribute("cart"); if (cart!=null){ //更新图书的数量 cart.updateCartItem(id,bookCount); } //得到图书项 CartItem cartItem = cart.getMap().get(id); //得到图书项的小计金额 double amount = cartItem.getAmount(); //得到所有图书项的总金额 double totalAmount = cart.getTotalAmount(); //得到所有图书项的总数量 int totalCount = cart.getTotalCount(); //将获取到的数据填充在map中 Map<String,Object> map=new HashMap<>(); map.put("amount",amount+""); map.put("totalCount",totalCount+""); map.put("totalAmount",totalAmount+""); Gson gson=new Gson(); String json = gson.toJson(map); response.setContentType("text/html;charset=utf-8"); //将JSON字符串响应到浏览器 response.getWriter().write(json); } protected void addCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //从页面获取id值 String id = request.getParameter("id"); //调用bookservice的方法获取得到books对象 Books books = bookService.selectBookById(Integer.parseInt(id)); //获取session HttpSession session = request.getSession(); //从session域中获取cart Cart cart = (Cart) session.getAttribute("cart"); if (cart==null){ //证明session域中还没有购物车,创建一个cart对象放在session中 cart = new Cart(); session.setAttribute("cart",cart); } //调用cart的添加方法, cart.addCartItem(books); //重定向到index页面 //response.sendRedirect(request.getContextPath()+"/index.jsp"); //获取请求头中的Referer属性值 String referer=request.getHeader("Referer"); //重定向到referer response.sendRedirect(referer); } protected void clear(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取session HttpSession session = request.getSession(); //从session域中获取cart Cart cart = (Cart) session.getAttribute("cart"); if (cart!=null){ cart.clearCartItem(); } //重定向到index页面 //response.sendRedirect(request.getContextPath()+"/index.jsp"); //获取请求头中的Referer属性值 String referer=request.getHeader("Referer"); //重定向到referer response.sendRedirect(referer); } protected void deleteCartItem(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取页面中参数id String id = request.getParameter("id"); //获取session HttpSession session = request.getSession(); //从session域中获取cart Cart cart = (Cart) session.getAttribute("cart"); if (cart!=null){ //调用cart对象的删除的方法 cart.deleteCartItem(id); } //重定向到index页面 //response.sendRedirect(request.getContextPath()+"/index.jsp"); //获取请求头中的Referer属性值 //重定向到购物车页面 response.sendRedirect(request.getContextPath()+"/pages/cart/cart.jsp"); } protected void updateCartItem(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取页面中参数id String id = request.getParameter("id"); //获取页面中的参数bookCount String bookCount = request.getParameter("bookCount"); //获取session HttpSession session = request.getSession(); //从session域中获取cart Cart cart = (Cart) session.getAttribute("cart"); if (cart!=null){ //调用cart对象的根更新的方法 cart.updateCartItem(id,bookCount); } //重定向到index页面 //response.sendRedirect(request.getContextPath()+"/index.jsp"); //获取请求头中的Referer属性值 //重定向到购物车页面 response.sendRedirect(request.getContextPath()+"/pages/cart/cart.jsp"); } }
第六阶段:结账、添加事务、使用ajax
- 1.创建订单类和订单项类
-
package com.atguigu.bean; import java.util.Date; //订单类 public class Order { private String id;//订单号 private Date orderTime;//生成订单的时间 private int totalCount;//购物车中图书的总数量 private double totalAmount;//购物车中图书的总金额 private int state;//订单的状态 0 未发货 1已发货 2交易完成 private int userId;//订单所属的用户 public Order(String id, Date orderTime, int totalCount, double totalAmount, int state, int userId) { this.id = id; this.orderTime = orderTime; this.totalCount = totalCount; this.totalAmount = totalAmount; this.state = state; this.userId = userId; } public Order() { } @Override public String toString() { return "Order{" + "id='" + id + '\'' + ", orderTime=" + orderTime + ", totalCount=" + totalCount + ", totalAmount=" + totalAmount + ", state=" + state + ", userId=" + userId + '}'; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Date getOrderTime() { return orderTime; } public void setOrderTime(Date orderTime) { this.orderTime = orderTime; } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public double getTotalAmount() { return totalAmount; } public void setTotalAmount(double totalAmount) { this.totalAmount = totalAmount; } public int getState() { return state; } public void setState(int state) { this.state = state; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } }
package com.atguigu.bean; public class OrderItem { private Integer id;//订单项的id private int count;//购物项中购买的图书数量 private double amount;//购物项中图书的金额小计 private String title;//书名 private String author; //作者 private double price; //图书的价格 private String imgPath; //图书的封面 private String orderId; //订单项所属的订单 public OrderItem() { } public OrderItem(int count, double amount, String title, String author, double price, String imgPath, String orderId) { this.count = count; this.amount = amount; this.title = title; this.author = author; this.price = price; this.imgPath = imgPath; this.orderId = orderId; } @Override public String toString() { return "OrderItem{" + "id=" + id + ", count=" + count + ", amount=" + amount + ", title='" + title + '\'' + ", author='" + author + '\'' + ", price=" + price + ", imgPath='" + imgPath + '\'' + ", orderId='" + orderId + '\'' + '}'; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public double getAmount() { return amount; } public void setAmount(double amount) { this.amount = amount; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getImgPath() { return imgPath; } public void setImgPath(String imgPath) { this.imgPath = imgPath; } public String getOrderId() { return orderId; } public void setOrderId(String orderId) { this.orderId = orderId; } public OrderItem(Integer id, int count, double amount, String title, String author, double price, String imgPath, String orderId) { this.id = id; this.count = count; this.amount = amount; this.title = title; this.author = author; this.price = price; this.imgPath = imgPath; this.orderId = orderId; } }
创建orderdao
-
public class OrderDaoImpl extends BaseDao<Order> implements OrderDao { @Override public void addOrder(Order order) { String sql="insert into orders(id,order_time,total_count,total_amount,state,user_id) values(?,?,?,?,?,?)"; update(sql, order.getId(), order.getOrderTime(), order.getTotalCount(), order.getTotalAmount(), order.getState(), order.getUserId()); } }
创建orderItemDao
-
public class OrderItemDaoImpl extends BaseDao<OrderItem> implements OrderItemDao { @Override public void addOrderItem(OrderItem orderItem) { String sql="insert into order_items(count,amount,title,author,price,img_path,order_id) values(?,?,?,?,?,?,?)"; update(sql,orderItem.getCount(),orderItem.getAmount(),orderItem.getTitle(),orderItem.getAuthor(),orderItem.getPrice(),orderItem.getImgPath(),orderItem.getOrderId()); } @Override public void batchAddOrderItems(Object[][] params) { String sql="insert into order_items(count,amount,title,author,price,img_path,order_id) values(?,?,?,?,?,?,?)"; batchUpdate(sql,params); } }
service层处理业务
-
package com.atguigu.service.Impl; import com.atguigu.bean.*; import com.atguigu.dao.BookDao; import com.atguigu.dao.Impl.BookDaoImpl; import com.atguigu.dao.Impl.OrderDaoImpl; import com.atguigu.dao.Impl.OrderItemDaoImpl; import com.atguigu.dao.OrderDao; import com.atguigu.dao.OrderItemDao; import com.atguigu.service.OrderService; import java.util.Date; import java.util.List; public class OrderServiceImpl implements OrderService { OrderDao orderDao=new OrderDaoImpl(); OrderItemDao orderItemDao=new OrderItemDaoImpl(); BookDao bookDao=new BookDaoImpl(); @Override public String checkout(Cart cart, User user) { //生成订单号 String orderId=System.currentTimeMillis()+""+user.getId(); //获取总数量 int totalCount = cart.getTotalCount(); //获取订单总额 double totalAmount = cart.getTotalAmount(); Order order = new Order(orderId, new Date(), totalCount, totalAmount, 0, user.getId()); //将订单加入数据库 orderDao.addOrder(order); //得到购物车中所有的图书项 List<CartItem> cartItems = cart.getCartItem(); for (CartItem cartItem1:cartItems){ //获取图书 Books books = cartItem1.getBooks(); //获取图书项的count数量 int count = (int)cartItem1.getCount(); //获取图书项的小计金额 double amount = cartItem1.getAmount(); //获取图书的书名 String title = books.getTitle(); //获取图书的作者 String author = books.getAuthor(); //获取单价 Double price = books.getPrice(); //获取图书图片 String imgPath = books.getImgPath(); //创建订单项 OrderItem orderItem = new OrderItem(null, count,amount,title,author,price,imgPath,orderId); //将订单项加入数据库 //设置图书的库存和销量 //库存-count,销量+count //获取当前库存 Integer stock = books.getStock(); //获取当前销量 Integer sales = books.getSales(); //在book中设置 books.setStock(stock-count); books.setStock(sales+count); //修改数据库的book bookDao.updateBook(books); } return orderId; }
servlet
-
在创建订单号的同时,也将订单和订单项加入到数据库中
-
protected void checkout(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取session对象 HttpSession session = request.getSession(); //从session域中拿出购物车和用户对象 Cart cart = (Cart) session.getAttribute("cart"); User user = (User) session.getAttribute("user"); //调用OrderService中的方法 String OrderId = orderService.checkout(cart, user); //设置到session域中 session.setAttribute("orderId",OrderId); // request.getRequestDispatcher("/pages/cart/checkout.jsp").forward(request,response); //重定向到显示订单号的页面 response.sendRedirect(request.getContextPath()+"/pages/cart/checkout.jsp"); }
添加事务
-
事务控制的关键:在同一个事务中,不同的操作要求使用同一个的数据库连接
- 如何保证使用同一个连接?使用ThreadLocal<T>对象保证一个线程对应一个数据库连接
- 然后使用过滤器控制事务
- 改变jdbcutils中的代码
-
package com.atguigu.utils; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; /** * ★通过德鲁伊连接池获取和释放连接的工具类(重点掌握) */ public class JDBCUtils { private static DataSource dataSource; //获取threadlocal的连接池 private static ThreadLocal<Connection> threadLocal=new ThreadLocal<>(); static { try { //1.创建Properties对象 Properties pro = new Properties(); InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"); //2.将类路径下的properties文件读成一个流 //3.加载properties文件 pro.load(is); //4.创建数据源 dataSource = DruidDataSourceFactory.createDataSource(pro); } catch (Exception e) { e.printStackTrace(); } } //获取同一个连接的方法 public static Connection getConnection(){ // Connection connection = null; // try { // //从数据源中获取连接 // connection = dataSource.getConnection(); // } catch (SQLException e) { // e.printStackTrace(); // } // return connection; Connection connection = threadLocal.get(); if (connection==null){ try { //在连接池中获取连接 connection = dataSource.getConnection(); //将连接与当前线程绑定 threadLocal.set(connection); } catch (SQLException throwables) { throwables.printStackTrace(); } } return connection; } //释放连接的方法 public static void releaseConnection(){ // if(connection != null){ // try { // connection.close(); // } catch (SQLException e) { // e.printStackTrace(); // } // } //从当前线程获取连接 Connection connection = threadLocal.get(); if (connection!=null){ try { //关闭连接 connection.close(); //将关闭的连接从threadlocal移除 threadLocal.remove(); } catch (SQLException throwables) { throwables.printStackTrace(); } } } }
使用过滤器过滤所有的请求
-
package com.atguigu.filter; import com.atguigu.utils.JDBCUtils; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; @WebFilter(filterName = "TranslicationFilter",urlPatterns = "/*") public class TranslicationFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //获取连接 Connection connection = JDBCUtils.getConnection(); try { //设置自动提交为false connection.setAutoCommit(false); //放行 chain.doFilter(req, resp); //放行之后进入servlet,serlet调用service,service调用dao,然后执行放行后的代码 //设置提交 connection.commit(); } catch (Exception throwables) { //出现异常,数据回滚 try { connection.rollback(); //重定向到错误页面 } catch (SQLException e) { e.printStackTrace(); } throwables.printStackTrace(); } } public void init(FilterConfig config) throws ServletException { } }
批处理:
-
在basedao中加入batchUpdate(String sql,Object[][] params)方法
-
package com.atguigu.utils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.sql.Connection; import java.sql.SQLException; import java.util.List; /** * 定义一个用来被继承的对数据库进行基本操作的Dao * * @author HanYanBing * * @param <T> */ public abstract class BaseDao<T> { private QueryRunner queryRunner = new QueryRunner(); //定义一个变量来接收泛型的类型 private Class<T> type; // 获取T的Class对象,获取泛型的类型,泛型是在被子类继承时才确定 public BaseDao() { //获取子类的类型 Class clazz = this.getClass(); //获取父类的类型 //getGenericSuperclass()用来获取当前类的父类的类型 //ParameterizedType表示的是带泛型的类型 ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass(); //获取具体的泛型类型 getActualTypeArguments获取具体的泛型的类型 //这个方法会返回一个Type的数组 Type[] types = parameterizedType.getActualTypeArguments(); //获取具体的泛型的类型· this.type = (Class<T>) types[0]; } /** * 通用的增删改操作 * * @param sql * @param params * @return */ public int update(String sql, Object... params) { // 获取连接 Connection connection = JDBCUtils.getConnection(); int count = 0; try { count = queryRunner.update(connection, sql, params); } catch (SQLException e) { //在进行订单操作时,出现错误的话在这里将异常捕获,不再抛去上一级,所以错误不在过滤器中捕获到,也无法提交事务, // 所以要在这里将编译时异常转换成运行时异常 // e.printStackTrace(); throw new RuntimeException(); } finally { JDBCUtils.releaseConnection(); } return count; } /** * 获取一个对象 * * @param sql * @param params * @return */ public T getBean(String sql, Object... params) { // 获取连接 Connection connection = JDBCUtils.getConnection(); T t = null; try { t = queryRunner.query(connection, sql, new BeanHandler<T>(type), params); } catch (SQLException e) { // e.printStackTrace(); throw new RuntimeException(); } finally { JDBCUtils.releaseConnection(); } return t; } /** * 获取所有对象 * @param sql * @param params * @return */ public List<T> getBeanList(String sql, Object... params) { // 获取连接 Connection connection = JDBCUtils.getConnection(); List<T> list = null; try { list = queryRunner.query(connection, sql, new BeanListHandler<T>(type), params); } catch (SQLException e) { // e.printStackTrace(); throw new RuntimeException(); } finally { JDBCUtils.releaseConnection(); } return list; } public Object getCount(String sql,Object ...params){ Connection connection = JDBCUtils.getConnection(); Object query =null; try { query=queryRunner.query(connection, sql, new ScalarHandler<>(),params); } catch (SQLException e) { // e.printStackTrace(); throw new RuntimeException(); }finally { JDBCUtils.releaseConnection(); } return query; } /** * 批处理的方法 * @param sql * @param params 传入一个二维数组的参数 * 二维数组的第一维是sql语句执行的次数 * 二维数组的第二维是执行每条sql语句时要填充的占位符 * */ public void batchUpdate(String sql,Object[][] params){ //获取连接 Connection connection = JDBCUtils.getConnection(); try { //调用queryRunner中的batch的方法 queryRunner.batch(connection,sql,params); } catch (SQLException throwables) { // throwables.printStackTrace(); //将编译时异常转换为运行时异常往上抛 throw new RuntimeException(); } } }
在orderItem中写sql语句
-
@Override public void batchAddOrderItems(Object[][] params) { String sql="insert into order_items(count,amount,title,author,price,img_path,order_id) values(?,?,?,?,?,?,?)"; batchUpdate(sql,params); }
在service中使用批量增加的方法
-
public class OrderServiceImpl implements OrderService { OrderDao orderDao=new OrderDaoImpl(); OrderItemDao orderItemDao=new OrderItemDaoImpl(); BookDao bookDao=new BookDaoImpl(); @Override public String checkout(Cart cart, User user) { //生成订单号 String orderId=System.currentTimeMillis()+""+user.getId(); //获取总数量 int totalCount = cart.getTotalCount(); //获取订单总额 double totalAmount = cart.getTotalAmount(); Order order = new Order(orderId, new Date(), totalCount, totalAmount, 0, user.getId()); //将订单加入数据库 orderDao.addOrder(order); //得到购物车中所有的图书项 List<CartItem> cartItems = cart.getCartItem(); //创建两个二维数组 Object[][] orderItemParams =new Object[cartItems.size()][]; Object[][] bookParams =new Object[cartItems.size()][]; //遍历图书项 for (int i=0;i<cartItems.size();i++){ //获取每一个购物项 CartItem cartItem = cartItems.get(i); //获取图书对象 Books books = cartItem.getBooks(); //获取书名 String title = books.getTitle(); //获取作者 String author = books.getAuthor(); //获取图书的价格 Double price = books.getPrice(); //获取图书的封面 String imgPath = books.getImgPath(); //获取购物项中图书的数量 int count = cartItem.getCount(); //获取购物项中图书的金额小计 double amount = cartItem.getAmount(); orderItemParams[i] = new Object[]{count, amount, title, author, price, imgPath, orderId}; //更新图书的库存和销量 //获取购物项中对应的库存和销量 Integer sales = books.getSales(); Integer stock = books.getStock(); //设置现在的销量为sales+count,库存为stock-count // book.setSales(sales+count); // book.setStock(stock-count); //更新图书 // bookDao.updateBook(book); //update books set sales = ? , stock = ? where id = ? bookParams[i] = new Object[]{sales+count,stock-count,books.getId()}; } // 清空购物车 cart.clearCartItem(); return orderId; } }
使用ajax请求使注册时显示用户已经存在的信息
-
创建servlet
-
//通过发送ajax请求验证用户名是否存在 protected void checkusername(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取应户名请求的参数 String username = request.getParameter("username"); //封存User对象 User user = new User(null,username,null,null); //调用UserService的方法 //创建userservice的实现类的对象 UserService userService=new UserServiceImpl(); boolean regist = userService.regist(user); response.setContentType("text/html;charset=utf-8"); if (regist){ response.getWriter().write("用户名已经存在"); }else { response.getWriter().write("<font color='green'>用户名可用!</font>"); } }
在jsp页面用jQuery写ajax请求
-
//给用户框设置改变事件 $("#username").change(function (){ //获取用户的用户名 let username = $(this).val(); //设置请求地址 var url="${pageContext.request.contextPath}/UserServlet?way=checkusername"; //设置请求参数 var params={"username":username}; $.post(url,params,function (res){ //将响应的信息设置到显示的span标签中 $("#usermsg").html(res); }); });
根据输入框的改变使用ajax请求改变图书项的总金额,改变所有的金额,改变总个数
-
在cartservlet中编写changeinput方法
-
protected void changeinput(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取id值 String id = request.getParameter("id"); //获取bookCount String bookCount = request.getParameter("bookCount"); //从session域中获取cart HttpSession session = request.getSession(); Cart cart = (Cart) session.getAttribute("cart"); if (cart!=null){ //更新图书的数量 cart.updateCartItem(id,bookCount); } //得到图书项 CartItem cartItem = cart.getMap().get(id); //得到图书项的小计金额 double amount = cartItem.getAmount(); //得到所有图书项的总金额 double totalAmount = cart.getTotalAmount(); //得到所有图书项的总数量 int totalCount = cart.getTotalCount(); //将获取到的数据填充在map中 Map<String,Object> map=new HashMap<>(); map.put("amount",amount+""); map.put("totalCount",totalCount+""); map.put("totalAmount",totalAmount+""); Gson gson=new Gson(); String json = gson.toJson(map); response.setContentType("text/html;charset=utf-8"); //将JSON字符串响应到浏览器 response.getWriter().write(json);
在cart.jsp页面使用ajax请求
-
var text = $(this).parent().next().next(); var url="cartServlet?way=changeinput"; var params={"id":id,"bookCount":bookCount}; $.post(url,params,function (ref){ //改变图书项的总金额 text.text(ref.amount); //改变总金额--%> $("#totalAmount").text(ref.totalAmount); //改变总个数--%> $("#totalCount").text(ref.totalCount); },"json");