团队成员
组长 | 徐佳澎 |
---|---|
组员 | 陈俊威 |
组员 | 赵洋 |
任务分配
徐佳彭 | jsp页面设计、servelet组件编写 |
---|---|
陈俊威、赵洋 | 类设计,dao方法编写,数据库表单设计 |
git仓库
git地址
git提交记录
前期调查
通过调查他人的图书管理系统是通过使用JSP、servlet技术实现在web端的查阅。
登录页面
能够查看图书的具体信息
浏览图书列表
参考链接
功能简述
该系统面向管理员可以实现对会员信息的管理,图书信息的修改与添加,借阅和归还功能
管理员信息的管理:有管理员的注册,账号密码的修改。
图书管理:能够实现图书的增、删、改、查功能,在web界面上能够显示书名、简介、出版社以及馆藏书籍数量。
借阅管理:图书借阅、图书归还。
用户管理:实现用户的注册以及删除若用户账户下仍有金额则无法删除),用户注册时需要如下信息:用户名、登录密码、账户余额、联系电话以及身份证号等。展示注册会员信息。
功能架构图
主要功能流程图
项目运行截图
1、登陆界面
2、登陆成功后的主界面
3、查看会员名单信息
4、查看书籍信息
5、添加书籍
6、借阅书籍
7、归还书籍
8、个人中心修改账号密码
关键代码描述
DBHelper类,为数据库帮助类,包含数据库的连接方法,是否启用回滚。首先判断连接的是事务的业务还是普通业务,普通的业务可以将其关闭,而事务的业务则不能随便关闭,得确保它内部的事务都已提交,同时为了确保应用程序、数据库的完整性,删除一个或多个部分完成的事务执行的更新,返回上一次正确状态行为
public class DBHelper {
static ComboPooledDataSource ds = new ComboPooledDataSource("mysql-book");
private static ThreadLocal<Connection> tl = new ThreadLocal<>();
static{
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
Connection conn = tl.get();
//如果从threadLocal中能够获取连接对象,那么说明当前是事务的业务
if(conn!=null){
return conn;
}
//普通业务,直接从数据源中获取连接对象
conn = ds.getConnection();
return conn;
}
public static void close(Connection conn, Statement st, ResultSet rs)throws SQLException{
//如果是事务中的连接对象,我们随意不能关闭,需要使用事务的提交获取回滚来关闭连接对象
Connection tlConn = tl.get();
//是事务中的连接对象,我们什么也不做
if(conn== tlConn){
return;
}
//不是事务的连接对象,我们能关闭
if(rs!=null){
rs.close();
}
if(st!=null){
st.close();
}
if(conn!=null){
DBHelper.close(conn);
}
}
public static void close(Connection conn)throws SQLException{
//如果是事务中的连接对象,我们随意不能关闭,需要使用事务的提交获取回滚来关闭连接对象
Connection tlConn = tl.get();
//是事务中的连接对象,我们什么也不做
if(tlConn == conn){
return;
}
//普通的情况
if(conn!=null){
conn.close();
}
}
/**
* 启动事务
*/
public static void beginTransaction() throws SQLException { //标记本地事务的起始点
//事务已经启动
Connection conn = tl.get();
if(conn !=null){
throw new RuntimeException("事务已启动") ;
}
//获取连接
conn = getConnection();
//存储到ThreadLocal中
tl.set(conn);
//设置手动提交
conn.setAutoCommit(false);
}
/**
* 提交事务
*/
public static void commitTransaction() throws SQLException { //标记一个成功的失误结束
//判断是否有未提交的事务
Connection conn = tl.get();
//没有事务
if(conn == null){
throw new RuntimeException("没有事务,提交失败");
}
//有,提交
conn.commit();
//3.将ThreadLocal中的内容删除
tl.remove();
//关闭连接对象
DBHelper.close(conn);
}
public static void rollbackTransaction() throws SQLException {
//判断是否有未提交的事务
Connection conn = tl.get();
if(conn == null){
throw new RuntimeException("没有事务,回滚失败");
}
//有,回滚
conn.rollback();
tl.remove();
DBHelper.close(conn);
}
public static void main(String[] args) {
try {
Connection connection = DBHelper.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
该方法是删除账户,其中要判断该用户的账户余额是否为0,如果不是则不能将该账户删除,如果该用户有外键则也不能删除,当这两者都不满足时则可以该用户信息删除
public int remove(long id) throws Exception {
//1.判断会员账号余额 >0 :提示不能删除
Member member = getById(id);
if(member.getBalance()>0){
throw new Exception("此会员消费金额大于0,删除失败");
}
//2.有外键不能删除
if(memberData.exits(id)){
throw new Exception("此会员有子信息,删除失败");
}
int count =0;
try {
count = memberData.remove(id);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return count;
}
验证码生成,能够在网页上显示验证码图形同时生成验证码信息。
package com.enjoy.book.action;
import javax.imageio.ImageIO;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
@WebServlet(urlPatterns = "/code.let",loadOnStartup = 1)
public class ValCodeServlet extends HttpServlet {
Random random =new Random();
/**
*获取验证码的符号,长度为四个字符
*/
private String getRandomStr(){
String str ="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
StringBuilder num =new StringBuilder();
int times=4;
for(int i=0;i<times;i++){
int index =random.nextInt(str.length());
num.append(str.charAt(index));
}
return num.toString();
}
private Color getBackColor(){
int red = random.nextInt(255);
int green = random.nextInt(255);
int blue = random.nextInt(255);
return new Color(red,green,blue);
}
private Color getForeColor(Color backColor){
int red = 255-backColor.getRed();
int green = 255-backColor.getGreen();
int blue = 255-backColor.getBlue();
return new Color(red,green,blue);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/**1.输出图片的类型
*
*/
resp.setContentType("image/jpeg");
BufferedImage bufferedImage =new BufferedImage(80,30, BufferedImage.TYPE_INT_RGB);
/**3.获取画布
*
*/
Graphics g= bufferedImage.getGraphics();
/**
*4.获取颜色
*/
Color bgColor = getBackColor();
g.setColor(bgColor);
/**5.画背景
*
*/
g.fillRect(0,0,100,50);
Color foreColor =getForeColor(bgColor);
g.setColor(foreColor);
g.setFont(new Font("黑体",Font.BOLD,24));
String randomStr =getRandomStr();
/**httpSession 用于验证码验证;
*
*/
HttpSession session =req.getSession();
session.setAttribute("code",randomStr);
/**画图,将随机字符串写进画布,设置位置
*
*/
g.drawString(randomStr,10,20);
ServletOutputStream print =resp.getOutputStream();
ImageIO.write(bufferedImage,"jpeg",print);
/**g.fillRect(0,0,80,30)
*
*/
}
}
bookservelet,实现在网页上对图书信息的修改
package com.enjoy.book.action;
import com.alibaba.fastjson.JSON;
import com.enjoy.book.bean.Book;
import com.enjoy.book.biz.BookBiz;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.util.List;
@WebServlet("/book.let")
/**
* @author 陈俊威
*/
public class BookServlet extends HttpServlet {
BookBiz bookBiz = new BookBiz();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
/**
* 地址
* /book.let?type=add 添加图书
* /book.let?type=modifypre&id=xx 修改前准备
* /book.let?type=modify 修改
* /book.let?type=remove&id=xx 删除
* /book.let?type=query&pageIndex=1 :分页查询(request:转发)
* /book.let?type=details&id=xx 展示书籍详细信息
* /book.let?type=doajax&name=xx :使用ajax查询图书名对应的图书信息
*
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
//验证用户是否登录
String state= req.getSession().toString();
if(state==null){
out.println("<script>alert('请登录');parent.window.location.href='login.html';</script>");
return;
}
String type = req.getParameter("type");
switch (type){
case "add":
try {
add1(req,resp,out);
} catch (Exception e) {
e.printStackTrace();
}
break;
case "modifypre":
//book.let?type=modifypre&id=xx
long bookId = Long.parseLong(req.getParameter("id"));
Book book = bookBiz.getById(bookId);
req.setAttribute("book",book);
req.getRequestDispatcher("book_modify1.jsp").forward(req,resp);
break;
case "modify":
try {
modify1(req,resp,out);
// modify(req,resp,out);
} catch (Exception e) {
e.printStackTrace();
}
break;
case "remove":
//1.获取删除的bookid
long removeId = Long.parseLong(req.getParameter("id"));
//2. 调用biz删除方法
try {
int count = bookBiz.remove(removeId);
if(count>0){
out.println("<script>alert('图书删除成功'); location.href='book.let?type=query&pageIndex=1';</script>");
}else{
out.println("<script>alert('图书删除失败'); location.href='book.let?type=query&pageIndex=1';</script>");
}
} catch (Exception e) {
e.printStackTrace();
out.println("<script>alert('"+e.getMessage()+"'); location.href='book.let?type=query&pageIndex=1';</script>");
}
//3. 提示+跳转=>out (查询的servlet)
break;
case "query":
query(req,resp,out);
break;
case "details":
details(req,resp,out);
break;
case "doajax":
String name = req.getParameter("name");
Book book2 = bookBiz.getByName(name);
if(book2==null){
out.print("{}");
}else{
out.print(JSON.toJSONString(book2));
}
break;
default:
resp.sendError(404);
}
}
/**
* 修改图书信息的方法
* @param req
* @param resp
* @param out
*/
private void add1(HttpServletRequest req, HttpServletResponse resp, PrintWriter out) throws Exception {
Book book =new Book();
book.setName(req.getParameter("name"));
book.setAddress(req.getParameter("address"));
book.setDesc(req.getParameter("desc"));
double price = Double.parseDouble(req.getParameter("price"));
book.setPrice(price);
long stock=Long.parseLong(req.getParameter("stock"));
book.setStock(stock);
book.setPublish(req.getParameter("publish"));
book.setAuthor(req.getParameter("author"));
int count = bookBiz.add(book);
if(count>0){
out.println("<script>alert('添加书籍成功');location.href='book.let?type=query&pageIndex=1';</script>");
}else{
out.println("<script>alert('添加书籍失败');location.href='book_add.jsp';</script>");
}
}
private void modify1(HttpServletRequest req, HttpServletResponse resp, PrintWriter out) throws Exception ,ClassCastException{
Book book=new Book();
book.setName(req.getParameter("name"));
book.setAddress(req.getParameter("address"));
long id =Long.parseLong(req.getParameter("id"));
book.setId(id);
book.setDesc(req.getParameter("desc"));
double price = Double.parseDouble(req.getParameter("price"));
book.setPrice(price);
long stock=Long.parseLong(req.getParameter("stock"));
book.setStock(stock);
book.setPublish(req.getParameter("publish"));
book.setAuthor(req.getParameter("author"));
System.out.println(book.toString());
int count = bookBiz.modify(book);
if(count>0){
out.println("<script>alert('修改书籍成功');location.href='book.let?type=query&pageIndex=1';</script>");
}else{
out.println("<script>alert('该书不存在,修改书籍失败');location.href='book.let?type=query&pageIndex=1';</script>");
}
}
/**
* 查看图书详情
* @param req
* @param resp
* @param out
*/
private void details(HttpServletRequest req, HttpServletResponse resp, PrintWriter out) throws ServletException, IOException {
//1.获取图书的编号
long bookId = Long.parseLong(req.getParameter("id"));
//2.根据编号获取图书对象
Book book = bookBiz.getById(bookId);
//3.将对象保存到req
req.setAttribute("book",book);
//4.转发到 jsp页面
req.getRequestDispatcher("book_details.jsp").forward(req,resp);
}
/**
* 查询
* book.let?type=query&pageIndex=1
* 页数: biz
* 当前页码:pageIndex = 1
* 存:request,转发
* @param req
* @param resp
* @param out
*/
private void query(HttpServletRequest req, HttpServletResponse resp, PrintWriter out) throws ServletException, IOException {
//1.获取信息(页数,页码,信息)
int pageSize = 10;
int pageCount = bookBiz.getPageCount( pageSize);
int pageIndex = Integer.parseInt(req.getParameter("pageIndex"));
if(pageIndex<1){
pageIndex = 1;
}
if(pageIndex>pageCount){
pageIndex = pageCount;
}
List<Book> books = bookBiz.getByPage(pageIndex,pageSize);
//2.存
req.setAttribute("pageCount",pageCount);
req.setAttribute("books",books);
//3. 转发到jsp页面,通过地址栏传页数
req.getRequestDispatcher("book_list.jsp?pageIndex="+pageIndex).forward(req,resp);
}
}
登录页面jsp设计
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>集美大学图书管理系统后台</title>
<link rel="stylesheet" type="text/css" href="./Style/style.css"/>
</head>
<body>
<div class="box">
<div class="box-small">
<div class="box-small-left">
</div>
<div class="box-small-right">
<div class="box-title">
<h3>集美大学图书管理系统</h3>
</div>
<div class="box-form">
<form id = "fmLogin" action="user.let?type=login" method="post">
<div class="box-form-name">
<h3>管理员:</h3>
<input type="text" name="name" value="" required/>
</div>
<div class="box-form-pwd">
<h3>密 码:</h3>
<input type="password" name="pwd" value="" required/>
</div>
<div class="box-form-val">
<h3>验证码:</h3>
<input type="text" name="valcode" value="" style="width:80px;" required/> <img src="code.let"/>
</div>
<div class="box-form-button">
<input type="submit" value="登录" /> <input type="reset" value="重填" />
</div>
</form>
</div>
</div>
</div>
</div>
</body>
</html>
项目代码扫描结果及改正
1、扫描结果
2、改正
项目总结
展望:该系统停留在用户和管理用使用同一个系统,希望后期能将用户和管理员系统分开处理,以达到不同需求者的方便使用系统