写在前面,之前由于种种原因博客好久没有更新。最近打算重拾JavaWeb,所以从头开始,先用servlet+jdbc+bootstrap最基础的代码实现一个图书系统。考虑有管理员端+用户端,项目完成后会上传至github,后期会升级ssh/ssm等,毕竟是温故学习,一点一点来,项目会一直更新补充!
github地址——https://github.com/vi3nty/BookSystem
2018.04.16更新,管理端进一步完善,页面优化调整
2018.03.29更新,管理端实现了过滤功能(管理端大部分功能已经完善,只剩下JS/JQ的还没有,等用户端写完了再说)
2018.03.26更新,管理端添加图书编辑页面(book.jsp),并采用了jquery的ajax技术
2018.03.22更新,管理端采用EL&JSTL进行了页面重构,并且添加分页功能
1.项目结构
│ .classpath
│ .gitignore
│ .project
│ LICENSE
│ README.md
│
├─.settings
│ .jsdtscope
│ org.eclipse.core.resources.prefs
│ org.eclipse.jdt.core.prefs
│ org.eclipse.wst.common.component
│ org.eclipse.wst.common.project.facet.core.xml
│ org.eclipse.wst.css.core.prefs
│ org.eclipse.wst.html.core.prefs
│ org.eclipse.wst.jsdt.ui.superType.container
│ org.eclipse.wst.jsdt.ui.superType.name
│
├─build
│ └─classes
│ ├─biz
│ │ │ AdminBiz.class
│ │ │ bookBiz.class
│ │ │
│ │ └─impl
│ │ AdminBizImpl.class
│ │ bookBizImpl.class
│ │
│ ├─dao
│ │ │ AdminDao.class
│ │ │ bookDao.class
│ │ │
│ │ └─impl
│ │ AdminDaoImpl.class
│ │ bookDaoImpl.class
│ │
│ ├─pojo
│ │ admin.class
│ │ book.class
│ │ PageBean.class
│ │
│ ├─servlet
│ │ AdminServlet.class
│ │ BookServlet.class
│ │ LogFilter.class
│ │ LoginServlet.class
│ │
│ └─utils
│ myDB.class
│
├─src
│ ├─biz
│ │ │ AdminBiz.java
│ │ │ bookBiz.java
│ │ │
│ │ └─impl
│ │ AdminBizImpl.java
│ │ bookBizImpl.java
│ │
│ ├─dao
│ │ │ AdminDao.java
│ │ │ bookDao.java
│ │ │
│ │ └─impl
│ │ AdminDaoImpl.java
│ │ bookDaoImpl.java
│ │
│ ├─pojo
│ │ admin.java
│ │ book.java
│ │ PageBean.java
│ │
│ ├─servlet
│ │ AdminServlet.java
│ │ BookServlet.java
│ │ LogFilter.java
│ │ LoginServlet.java
│ │
│ └─utils
│ myDB.java
│
└─WebContent
├─css
│ bootstrap-theme.css
│ bootstrap-theme.css.map
│ bootstrap-theme.min.css
│ bootstrap-theme.min.css.map
│ bootstrap.css
│ bootstrap.css.map
│ bootstrap.min.css
│ bootstrap.min.css.map
│
├─fonts
│ glyphicons-halflings-regular.eot
│ glyphicons-halflings-regular.svg
│ glyphicons-halflings-regular.ttf
│ glyphicons-halflings-regular.woff
│ glyphicons-halflings-regular.woff2
│
├─img
│ │ duzhe.jfif
│ │ qingnian.jfif
│ │ s28350186.jpg
│ │ s29643861.jpg
│ │ s29672551.jpg
│ │ s29686001.jpg
│ │
│ └─readme
│ admin.PNG
│
├─js
│ bootstrap.js
│ bootstrap.min.js
│ jquery-3.3.1.js
│ npm.js
│
├─META-INF
│ MANIFEST.MF
│
├─web
│ admin.jsp
│ AdminLogin.jsp
│ book.jsp
│
└─WEB-INF
│ web.xml
│
└─lib
mysql-connector-java-5.1.46-bin.jar
taglibs-standard-impl-1.2.5.jar
taglibs-standard-spec-1.2.5.jar
项目采取最基础的MVC分层架构,全部采用servlet+jdbc方式实现。jsp作为v层,servlet作为controller层与业务层代码关联,整个代码做到最大限度的低耦合。前端主要是jQuery和Bootstrap,毕竟我前端了解的少,仅仅会用几个API,所以整个项目前端不做过多赘述。
2.项目分层概述
①dao层主要是处理与数据库交互的逻辑
AdminDao.java
1 public interface AdminDao { 2 public boolean adminLogin(String admin,String password); 3 }
AdminDaoImpl.java
1 public class AdminDaoImpl implements AdminDao{ 2 public boolean adminLogin(String admin, String password) { 3 Connection conn=null; 4 PreparedStatement st=null; 5 ResultSet rs=null; 6 Boolean result=false; 7 try { 8 //获取连接 9 conn=myDB.getConnection(); 10 //编写SQL语句 11 String adminLoginSql="select * from aduser where adname='"+admin+"' and password='"+password+"'"; 12 //创建语句执行者 13 st=conn.prepareStatement(adminLoginSql); 14 //获取结果 15 rs=st.executeQuery(); 16 if(rs.next()) 17 result=true; 18 else 19 result=false; 20 } catch (Exception e) { 21 e.printStackTrace(); 22 } 23 finally { 24 myDB.closeResource(conn, st, rs); 25 } 26 return result; 27 } 28 }
②biz层主要是业务逻辑的实现
AdminBiz类似Dao层,所以就不贴代码了
AdminBizImpl.java
1 public class AdminBizImpl implements AdminBiz{ 2 private AdminDao adminDao; 3 public boolean adminLogin(String admin, String password) { 4 //实例化接口 5 adminDao=new AdminDaoImpl(); 6 pojo.admin admin2=new pojo.admin(); 7 admin2.setAdmin(admin); 8 admin2.setPassword(password); 9 Boolean result=adminDao.adminLogin(admin2.getAdmin(), admin2.getPassword()); 10 return result; 11 } 12 }
③utils是工具类,主要有数据库连接的类,这样每次操作数据库不用重写代码
④pojo层是数据库表的映射实体类
PageBean.java类主要用于图书分页实现
1 public class PageBean<T> { 2 private int currentPage=1;//当前页,默认显示第一页 3 private int pageCount=5;//每页显示的行数 4 private int totalCount;//总记录数 5 private int totalPage;//总页数=总记录数/每页显示的行数+1 6 private List<T> pageData; 7 8 //获取总页数 9 public int getTotalPage() { 10 if(totalCount%pageCount==0) 11 totalPage=totalCount/pageCount;//被整除情况 12 else { 13 totalPage=totalCount/pageCount+1; 14 } 15 return totalPage; 16 } 17 public void setTotalPage(int totalPage) { 18 this.totalPage=totalPage; 19 } 20 public int getCurrentPage() { 21 return currentPage; 22 } 23 public void setCurrentPage(int currentPage) { 24 this.currentPage = currentPage; 25 } 26 public int getPageCount() { 27 return pageCount; 28 } 29 public void setPageCount(int pageCount) { 30 this.pageCount = pageCount; 31 } 32 public int getTotalCount() { 33 return totalCount; 34 } 35 public void setTotalCount(int totalCount) { 36 this.totalCount = totalCount; 37 } 38 public List<T> getPageData() { 39 return pageData; 40 } 41 public void setPageData(List<T> pageData) { 42 this.pageData = pageData; 43 } 44 }
⑤servlet控制层
AdminServlet.java类(用于图书管理端分页等功能的实现)
1 public class AdminServlet extends HttpServlet{ 2 @Override 3 protected void service(HttpServletRequest req, HttpServletResponse rep) throws ServletException, IOException { 4 int currentPage;//获得当前页 5 String current=(String) req.getParameter("page"); 6 if(current==null) 7 currentPage=1; 8 else 9 currentPage=Integer.parseInt(current); 10 //实例化业务层 11 bookBiz bookbiz=new bookBizImpl(); 12 PageBean pb=new PageBean(); 13 pb.setTotalCount(bookbiz.getTotalCount()); 14 if(currentPage>0) 15 pb.setCurrentPage(currentPage); 16 //分页查询 17 ArrayList<book> books=bookbiz.searchAllBook(pb); 18 //获得总页数 19 int pageCount=pb.getTotalPage(); 20 //将book集合和页面数跳转至admin.jsp页面 21 req.setAttribute("bookslist", books); 22 req.setAttribute("pagesize", pageCount); 23 req.getRequestDispatcher("web/admin.jsp").forward(req, rep); 24 } 25 }
BookServlet.java类(用于图书编辑修改等的实现)
1 public class BookServlet extends HttpServlet{ 2 @Override 3 protected void service(HttpServletRequest req, HttpServletResponse rep) throws ServletException, IOException { 4 int bookid=Integer.parseInt(req.getParameter("bookid")); 5 bookBiz bookbiz=new bookBizImpl(); 6 book bk=bookbiz.getBookById(bookid); 7 if(req.getParameter("method")!=null&&req.getParameter("method").equals("update")) { 8 int borrow=Integer.parseInt(req.getParameter("borrow")); 9 String intro=req.getParameter("intro"); 10 if(bookbiz.editBook(bookid, intro, borrow)) { 11 //req.setAttribute("bk", bk); 12 //req.getRequestDispatcher("bookServlet?bookid="+bookid).forward(req, rep); 13 PrintWriter out=rep.getWriter(); 14 out.println("success"); 15 } 16 } 17 else { 18 //将获取到的book数据发送并跳转至book.jsp页面 19 req.setAttribute("bk", bk); 20 req.getRequestDispatcher("web/book.jsp?bookid="+bookid).forward(req, rep); 21 } 22 } 23 }
LogFilter.java类(用于登录过滤实现)
1 public class LogFilter implements Filter{ 2 private FilterConfig config; 3 @Override 4 public void destroy() { 5 // TODO Auto-generated method stub 6 7 } 8 /* 9 * Filter的核心处理 10 * */ 11 @Override 12 public void doFilter(ServletRequest req, ServletResponse rep, FilterChain filc) 13 throws IOException, ServletException { 14 HttpServletRequest request=(HttpServletRequest) req; 15 HttpServletResponse response=(HttpServletResponse) rep; 16 HttpSession session=request.getSession(); 17 //如果session中有logined,则证明过滤成功 18 if(session.getAttribute("logined")!=null) { 19 filc.doFilter(req, rep); 20 } 21 else 22 response.sendRedirect("web/AdminLogin.jsp"); 23 } 24 25 @Override 26 public void init(FilterConfig config) throws ServletException { 27 this.config=config; 28 } 29 30 }
3.数据库设计
aduser表
4.前端JSP设计
①AdminLogin.jsp页面
1 <%@ page language="java" contentType="text/html; charset=utf-8" 2 pageEncoding="utf-8"%> 3 <!DOCTYPE html> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 7 <title>管理员登录页面</title> 8 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 9 <link rel="stylesheet" href="../css/bootstrap.css"> 10 <script type="text/javascript" src="../js/bootstrap.js"></script> 11 <script> 12 13 </script> 14 </head> 15 <body> 16 <div class="continer"> 17 <div style="margin:0 auto"> 18 <h2 class="text-center">图书管理系统</h2> 19 <form class="form-horizontal" role="form" action="/BookSystem/adminlogin" method="post"> 20 21 <div class="form-group"> 22 <label for="username" class="col-sm-2 control-label">用户名:</label> 23 <div class="col-sm-5"> 24 <input type="text" class="form-control" name="adname" id="adname" 25 placeholder="请输入用户名"> 26 </div> 27 </div> 28 <div class="form-group"> 29 <label for="password" class="col-sm-2 control-label">密码:</label> 30 <div class="col-sm-5"> 31 <input type="password" class="form-control" name="password" id="password" 32 placeholder="请输入密码"> 33 </div> 34 </div> 35 <div class="form-group"> 36 <div class="col-sm-offset-2 col-sm-10"> 37 <input type="submit" class="btn btn-default" value="登录"/> 38 </div> 39 </div> 40 41 </form> 42 </div> 43 </div> 44 </body> 45 </html>
②admin.jsp页面(管理端)
1 <%@page import="pojo.PageBean"%> 2 <%@page import="pojo.book"%> 3 <%@page import="java.util.ArrayList"%> 4 <%@page import="biz.impl.bookBizImpl"%> 5 <%@page import="biz.bookBiz"%> 6 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 7 <%@ page language="java" contentType="text/html; charset=utf-8" 8 pageEncoding="utf-8"%> 9 <!DOCTYPE> 10 <html> 11 <head> 12 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 13 <title>管理页面</title> 14 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 15 <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.css"> 16 <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap-theme.css"> 17 <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css"> 18 <script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.js"></script> 19 <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script> 20 </head> 21 <body> 22 <div class="container"> 23 <div class="row"> 24 <div class="col-sm-12"> 25 <h3 class="text-center"> 26 图书系统管理员端 27 </h3> 28 <div class="row"> 29 <div class="col-sm-2"> 30 <div class="btn-group-vertical"> 31 <button class="btn btn-primary" type="button">书籍管理</button> <button class="btn btn-primary" type="button">添加书籍</button> <button class="btn btn-primary" type="button">用户管理</button> 32 </div> 33 </div> 34 <div class="col-sm-8" id="booklist"> 35 <table class="table table-striped"> 36 <thead> 37 <tr> 38 <th>书籍封面</th> 39 <th>书籍名称</th> 40 <th>是否借出</th> 41 <th>书籍作者</th> 42 <th>分类目录</th> 43 <th>简介</th> 44 <th>操作</th> 45 </tr> 46 </thead> 47 <!-- 03.22采用EL&JSTL进行页面 重构 --> 48 <tbody> 49 <c:forEach items="${requestScope.bookslist}" var="book"> 50 <tr> 51 <td style="12%"> 52 <div class="thumbnail" > 53 <img src="http://${book['bk_img']}"> 54 </div> 55 </td> 56 <td> 57 <p id="bookname">${book['bk_name']}</p> 58 </td> 59 <td> 60 <p> 61 62 <c:if test="${book['bk_borrowed']}==1"> 63 <c:out value="已借出"></c:out> 64 </c:if> 65 <c:if test="${book['bk_borrowed']}==0"> 66 <c:out value="未借出"></c:out> 67 </c:if> 68 </p> 69 </td> 70 <td> 71 <p id="bookname">${book['bk_name']}</p> 72 </td> 73 <td> 74 <p id="bookname">${bk['bk_category']}</p> 75 </td> 76 <td> 77 <p id="bookname">${book['bk_intro']}</p> 78 </td> 79 <td> 80 <div class="btn-group-vertical"> 81 <button class="btn btn-primary" type="button">编辑</button> <button class="btn btn-primary" type="button">删除</button> 82 </div> 83 </td> 84 </tr> 85 </c:forEach> 86 </tbody> 87 </table> 88 <ul class="pagination"> 89 <li><a href="adminServlet?page=${param.page-1}" <c:if test="${param.page==1}">class="btn disabled"</c:if>>«</a></li> 90 <c:forEach var="i" begin="1" end="${pagesize}"> 91 <li id="bookitem"><a href="adminServlet?page=<c:out value='${i}'/>" <c:if test="${i==param.page}">class="btn disabled"</c:if>><c:out value="${i}"/></a></li> 92 </c:forEach> 93 <li><a href="adminServlet?page=${param.page+1}" <c:if test="${param.page==pagesize}">class="btn disabled"</c:if>>»</a></li> 94 </ul> 95 </div> 96 <div class="col-sm-2"> 97 <form class="form-search"> 98 <input class="form-control" type="text" /> <button type="submit" class="btn">查找</button> 99 </form> 100 </div> 101 </div> 102 </div> 103 </div> 104 </div> 105 </body> 106 </html>
③book.jsp(图书编辑页面)
1 <%@ page language="java" contentType="text/html; charset=utf8" 2 pageEncoding="utf8"%> 3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 4 <!DOCTYPE html> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=utf8"> 8 <title>编辑图书</title> 9 <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.css"> 10 <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap-theme.css"> 11 <link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css"> 12 <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script> 13 <script type="text/javascript" src="${pageContext.request.contextPath}/js/bootstrap.js"></script> 14 <script type="text/javascript"> 15 function edbook(){ 16 $.ajax({ 17 url:"bookServlet?method=update&bookid=${bk['bk_id']}", 18 type:"post", 19 data:$("#edit").serialize(), 20 cache:false, 21 dataType: "text", 22 error:function(err){ 23 alert("更新失败!"); 24 }, 25 success:function(msg){ 26 alert("更新成功!"); 27 } 28 }); 29 } 30 31 </script> 32 </head> 33 <body> 34 <div class="container"> 35 <h3 class="text-center"> 36 管理员端 37 </h3> 38 <div class="col-md-8 col-md-offset-2"> 39 <form method="post" id="edit"> 40 <table class="table table-bordered"> 41 <tr> 42 <th>书籍名称</th> 43 <td>${bk['bk_name']}</td> 44 </tr> 45 <tr> 46 <th>是否借出</th> 47 <td> 48 <select class="selectpicker show-tick form-control" name="borrow" id="borrow" title="请选择一项" data-live-search="true" data-size="5"> 49 <option role="presentation" <c:if test="${bk['bk_borrowed']==1}">selected</c:if> value="1">已借出</option> 50 <option role="presentation" <c:if test="${bk['bk_borrowed']==0}">selected</c:if> value="0">未借出</option> 51 </select> 52 </td> 53 </tr> 54 <tr> 55 <th>书籍作者</th> 56 <td>${bk['bk_author']}</td> 57 </tr> 58 <tr> 59 <th>书籍分类</th> 60 <td> 61 ${bk['bk_category']} 62 </td> 63 </tr> 64 <tr> 65 <th>书籍介绍</th> 66 <td><textarea class="form-control" rows="3" id="intro" name="intro">${bk['bk_intro']}</textarea></td> 67 </tr> 68 <tr><th></th><td><input type="submit" class="btn default" onclick="edbook()" value="提交" id="editbook" name=""/></td></tr> 69 </table> 70 </form> 71 </div> 72 </div> 73 </body> 74 </html>