写在前面,之前由于种种原因博客好久没有更新。最近打算重拾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="width: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>
5.web.xml等配置文件
来源:oschina
链接:https://my.oschina.net/u/4324861/blog/4277738