基于Tomcat+servlet+jsp实现的图书管理系统

很久以前写过基于tomcat的通讯录,但那其中遇到的问题我是一个都不记得了,自然也不记得当时配置环境有多么困难,这次重新写基于tomcat的项目,在最初的环境配置上就遇到了许多问题,磕磕绊绊也是解决了,在放项目代码之前首先描述一下问题与解决方法。

问题与解决方法

1、tomcat访问项目的路径中一直有项目名(war_exploded)。

网上的解决方案我看了很多 ,也一一跟着改了,server.xml改了,edit configuration改了,但没一个解决了我的问题,哪怕清空idea缓存,重启idea和tomcat也没有作用。

解决方法:
我用的笨方法,(聪明方法我用了是一点作用没有,可能我电脑随我,聪明不来)首先确实是要修改server.xml,在host中加上这么一行,其中path表示直接访问docBase路径,docBase则是项目所在地(我把项目放在了tomcat的webapps里,如果不放这里的话,docbase里也可以放绝对路径)

<Context path="/" docBase="/3_BookManage" debug="0" reloadable="true" />

其次是在idea里修改tomcat的加载方式与访问路径

2、一直加载修改前的项目

在我大改完我的项目后(删掉一些jsp界面与servlet),项目还是锲而不舍地访问我删掉的界面,搞得我非常困惑,毕竟我也尝试重新编译过了,后来我遍历整个项目,发现只有一个地方还存在我删除的文件,那就是在out里

最初我把整个out文件夹下的内容都删了,重新运行项目,此时out文件夹可以正常获取到servlet的文件数据,但是jsp文件直接报了404,后来我直接将项目中的web文件夹里的内容放到out的artifacts中,终于项目正常运行了。

3、项目的导包问题


需要三个包

 

 

最开始我只通过project structure把需要的包导进了项目,但此时jsp一直无法获取到数据库的数据,后来才发现,把包导在web里就可以了。有两个包,在我导入之后一直不起作用,在我bulid之后代码依旧标红,后来我右键jar包,将他们加入library root,此时就没有报错了,包已成功导入。

开始介绍项目情况 

项目目录

Book实体类:
 

​​package book.bean;

public class Book {

    /**
     * 序号
     */
    private int id;
    /**
     * 书名
     */
    private String bookname;
    /**
     * 作者
     */
    private String author;
    /**
     * 出版社
     */
    private String introduce;
    /**
     * 价格
     */
    private int price;
    /**
     * 状态
     */
    private String status;
    /**
     * 入馆时间
     */
    private String entry_time;


    /**
     * book
     */
    private static final long serialVersionUID = 1L;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getBookname() {
        return bookname;
    }

    public void setBookname(String bookname) {
        this.bookname = bookname == null ? null : bookname.trim();
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author == null ? null : author.trim();
    }

    public String getIntroduce() {
        return introduce;
    }

    public void setIntroduce(String introduce) {
        this.introduce = introduce;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getEntry_time() {
        return entry_time;
    }

    public void setEntry_time(String entry_time) {
        this.entry_time = entry_time;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", bookname=").append(bookname);
        sb.append(", author=").append(author);
        sb.append(", introduce=").append(introduce);
        sb.append(", price=").append(price);
        sb.append(", status=").append(status);
        sb.append(", entry_time=").append(entry_time);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}

BookDaoImpl数据库crud

package book.dao.impl;

import book.bean.Book;
import book.bean.User;
import book.dao.BookDao;
import book.db.ConnectionFactory;
import book.db.DBClose;
import book.db.BaseDB;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class BookDaoImpl implements BookDao {
    private Connection conn =null;
    private PreparedStatement pstate=null;
    private ResultSet rs=null;

   public List<Book> findAllBooks(){
       try{
           conn = ConnectionFactory.getConnection();
           String sql="select * from book";
           pstate = conn.prepareStatement(sql);
           rs = pstate.executeQuery();
           List<Book> books= new ArrayList();
           while(rs.next()){
               Book book=new Book();//记得把对象new在循环里,每set一遍需要new一个对象。
               int id=rs.getInt("id");
               String bookname=rs.getString("bookname");
               String author=rs.getString("author");
               String introduce=rs.getString("introduce");
               int price=rs.getInt("price");
               String status=rs.getString("status");
               String entry_time=rs.getString("entry_time");

               book.setId(id);
               book.setBookname(bookname);
               book.setAuthor(author);
               book.setIntroduce(introduce);
               book.setPrice(price);
               book.setStatus(status);
               book.setEntry_time(entry_time);
               books.add(book);
           }

//           for(int i=0;i<books.size();i++){
//               System.out.println("findAllBooks====="+books.get(i).getAuthor());
//           }
           return books;
       }catch(SQLException e){
           e.printStackTrace();
       }
       return null;
    }

    public Book findByIDBook(Integer id){
        try{
            conn = ConnectionFactory.getConnection();
            String sql="select * from book where id=?";
            pstate = conn.prepareStatement(sql);
            pstate.setInt(1,id);
            rs = pstate.executeQuery();
            Book book=null;
            while(rs.next()){
                book = new Book();
                int ids=rs.getInt("id");
                String bookname=rs.getString("bookname");
                String author=rs.getString("author");
                String introduce=rs.getString("introduce");
                int price=rs.getInt("price");
                String status=rs.getString("status");
                String entry_time=rs.getString("entry_time");

                book.setId(ids);
                book.setBookname(bookname);
                book.setAuthor(author);
                book.setIntroduce(introduce);
                book.setPrice(price);
                book.setStatus(status);
                book.setEntry_time(entry_time);
            }
            return book;
        }catch(SQLException e){
            e.printStackTrace();
        }
        return null;
    }

    public List<Book> findByCondition(String book_name,String book_status){
        try{
            conn = ConnectionFactory.getConnection();

            String sql="select * from book where 1=1 ";
            StringBuffer sb=new StringBuffer(sql);
            List l = new ArrayList<>();
            if(book_name!=null && book_name!=""){
                sb.append("and bookname like '%' ? '%' ");
                l.add(book_name);
            }
            if(book_status!=null && book_status!=""){
                sb.append(" and status like '%' ? '%' ");
                l.add(book_status);
            }

            pstate = conn.prepareStatement(sb.toString());
            for(int i=1;i<=l.size();i++){
                pstate.setObject(i,l.get(i-1));
            }
            rs = pstate.executeQuery();
            List<Book> books= new ArrayList();
            while(rs.next()){
                Book book=new Book();
                int id=rs.getInt("id");
                String bookname=rs.getString("bookname");
                String author=rs.getString("author");
                String introduce=rs.getString("introduce");
                int price=rs.getInt("price");
                String status=rs.getString("status");
                String entry_time=rs.getString("entry_time");

                book.setId(id);
                book.setBookname(bookname);
                book.setAuthor(author);
                book.setIntroduce(introduce);
                book.setPrice(price);
                book.setStatus(status);
                book.setEntry_time(entry_time);
                books.add(book);
            }
            return books;
        }catch(SQLException e){
            e.printStackTrace();
        }
        return null;
    }


    public int addBook(Book book){
        //生成entry_time字段
        // 获取当前时间的毫秒级时间戳
        long timestamp = System.currentTimeMillis();
        // 创建SimpleDateFormat对象,并设置日期格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 将时间戳转换为字符串
        String formattedTimestamp = sdf.format(new Date(timestamp));

        try{
            conn = ConnectionFactory.getConnection();
            String sql="insert into book(bookname,author,introduce,price,status,entry_time) values(?,?,?,?,?,?)";
            pstate = conn.prepareStatement(sql);

            pstate.setString(1,book.getBookname());
            pstate.setString(2,book.getAuthor());
            pstate.setString(3,book.getIntroduce());
            pstate.setInt(4,book.getPrice());
            pstate.setString(5,book.getStatus());

            pstate.setString(6,formattedTimestamp);
            int i = pstate.executeUpdate();
            return i;

        }catch(SQLException e){
            e.printStackTrace();
        }finally {
            DBClose.close(rs,pstate,conn);
        }
       return 0;
    }
    public int modifyBook(Book book){
        try{

            conn = ConnectionFactory.getConnection();
            String sql="update book set bookname=?,author=?,introduce=?,price=?,status=? where id=?";
            pstate = conn.prepareStatement(sql);

            pstate.setString(1,book.getBookname());
            pstate.setString(2,book.getAuthor());
            pstate.setString(3,book.getIntroduce());
            pstate.setInt(4,book.getPrice());
            pstate.setString(5,book.getStatus());
            pstate.setInt(6,book.getId());

            System.out.println("在BookDaoImpl层中modifyBook函数------Book"+book.getBookname());

            int flag = pstate.executeUpdate();

            System.out.println("在BookDaoImpl层中modifyBook函数------"+flag);


            return flag;

        }catch(SQLException e){
            e.printStackTrace();
        }finally {
            DBClose.close(rs,pstate,conn);
        }
       return 0;
    }
    public int deleteBook(Integer id){
        try{
            conn = ConnectionFactory.getConnection();
            String sql="delete from book where id=?";
            pstate = conn.prepareStatement(sql);
            pstate.setInt(1,id);
            int i = pstate.executeUpdate();
            return i;
        }catch(SQLException e){
            e.printStackTrace();
        }finally {
            DBClose.close(rs,pstate,conn);
        }
        return 0;
    }
    public void deleteByIds(String[] ids){
        System.out.println("进入了deleteBuIds");
        for(String id:ids){
            System.out.println("deleteBuIds的id==="+id);
            deleteBook(Integer.parseInt(id));
        }
    }


    public String modifyStatusBook(Integer id){
        int rowsAffected=0;
       String nstatus=null;
        //生成entry_time字段
        // 获取当前时间的毫秒级时间戳
        long timestamp = System.currentTimeMillis();
        // 创建SimpleDateFormat对象,并设置日期格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 将时间戳转换为字符串
        String formattedTimestamp = sdf.format(new Date(timestamp));
       try{

           Book book =findByIDBook(id);
           if (book == null) {
               throw new SQLException("Status not found for id: " + id);
           }
           String status=book.getStatus();
           System.out.println(id+"=====预备修改status之前为-----"+book.getStatus());
           if(status!=null && status.contains("已借出")){
               nstatus="可借阅";
           }else if(status!=null && status.contains("可借阅")){
               nstatus="已借出";
           }
           String sql;
            if(nstatus.contains("已借出")){
                sql = "update book set status=? where id=?";

            }else {
                sql="update book set status=?,entry_time=? where id=?";

            }
           conn = ConnectionFactory.getConnection();
           pstate = conn.prepareStatement(sql);
           pstate.setString(1, nstatus);

           // 如果状态不是可借阅,则设置entry_time
           if (nstatus.contains("可借阅")) {
               pstate.setString(2, formattedTimestamp);
               pstate.setInt(3, id);
           } else {
               pstate.setInt(2, id);
           }

           rowsAffected = pstate.executeUpdate();
           System.out.println("row  modifyStatusBook受影响的行数====" + rowsAffected);

           return nstatus;


       }catch(SQLException e){
        e.printStackTrace();
    }
    return null;
    }


}

BookManageServlet,展示数据库所有图书
 

package book.servlet;

import book.bean.Book;
import book.service.impl.BookServiceImpl;

import javax.servlet.RequestDispatcher;
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 java.io.IOException;
import java.util.List;

@WebServlet("/bookmanageservlet")
public class BookManageServlet extends HttpServlet {
    public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        doGet(request,response);
    }

    public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
        //解决乱码
        request.setCharacterEncoding("UTF-8");

        BookServiceImpl service = new BookServiceImpl();

        List<Book> books = service.findAllBooks();
        request.setAttribute("books",books);
//        System.out.println("进入doGet----booklistservlet");

        for(int i=0;i<books.size();i++){
            System.out.println(books.get(i).getAuthor());
        }
        int count=books.size();
        request.setAttribute("count",count);
        //查到所有数据转发到 文件 中进行展示
//            request.getRequestDispatcher("/views/index.jsp").forward(request,response);
        this.gotoPage("/views/index.jsp", request, response);
    }

    //定义私有方法,实现请求转发
    private void gotoPage(String url,HttpServletRequest request,HttpServletResponse response)
            throws ServletException,IOException{
        RequestDispatcher dispatcher=request.getRequestDispatcher(url);
        dispatcher.forward(request,response);
    }
}

index.jsp主页界面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<c:set var="pagePath" value="${pageContext.request.contextPath}" />

<!DOCTYPE html>
<html>
<head>
	<jsp:include page="head.jsp">
		<jsp:param value="图书管理系统" name="title" />
	</jsp:include>
	<link rel="stylesheet" type="text/css" href="css/styleOfIndex.css">
	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
	<style>
		.borrowed-book {
			background-color: yellow;
		}
		.navbar {
			text-align: center;
			background: #080808;
			padding: 10px;
		}
		.navbar-buttons a {
			margin: 0 10px;
			text-decoration: none;
			color: #333;
		}
		.search-container {
			text-align: center;
			margin: 20px 0;
		}
		#booksTable {
			width: 100%;
			border-collapse: collapse;
		}
		#booksTable th, #booksTable td {
			border: 1px solid #ddd;
			padding: 8px;
		}
		#booksTable th {
			background-color: #f2f2f2;
		}
		a:link {
			text-decoration: none;
		}
		/*a:hover 指鼠标在链接上; */
		a:hover {
			color:green;
		}	</style>
</head>
<body>

<div class="navbar">
	<h1 style="margin-right: 1100px;color: #f1f1f1">图书管理系统</h1>
	<div class="navbar-buttons" style="margin-left: 1200px;">
		<a href="/views/book/add.jsp" style="color: aliceblue">新增图书</a>
		<a href="/bookmanageservlet" style="color: aliceblue">返回</a>
	</div>
</div>

<%--<form action="findByConditionServlet" method="get">--%>
<%--	<div class="search-container">--%>
<%--		<input type="text" name="bookname" placeholder="输入图书名进行查询">--%>
<%--		可借阅:<input type="radio" name="status" value="可借阅">--%>
<%--		已借出:<input type="radio" name="status" value="已借出">--%>
<%--		<input type="submit" value="搜索"/>--%>
<%--	</div>--%>
<%--</form>--%>
<%--<form action="findByConditionServlet" method="get">--%>
<%--	<div class="search-container">--%>
<%--		<input type="text" name="bookname" placeholder="输入图书名进行查询">--%>
<%--		状态:--%>
<%--		<select name="status">--%>
<%--			<option value="可借阅">可借阅</option>--%>
<%--			<option value="已借出">已借出</option>--%>
<%--		</select>--%>
<%--		<input type="submit" value="搜索"/>--%>
<%--	</div>--%>
<%--</form>--%>
<form action="findByConditionServlet" method="get">
	<div class="search-container">
		<input type="text" name="bookname" placeholder="输入图书名进行查询">
		状态:
		<select name="status">
			<option value="可借阅" <c:if test="${param.status == '可借阅'}">selected</c:if>>可借阅</option>
			<option value="已借出" <c:if test="${param.status == '已借出'}">selected</c:if>>已借出</option>
		</select>
		<input type="submit" value="搜索"/>
	</div>
</form>

<form action="/deleteByIds"  method="post" id="deleteForm" >
	<table id="booksTable" align="center">
		<tr>
			<th><label for="select-all-checkbox">全选</label><input type="checkbox" id="select-all-checkbox" class="select-checkbox"></th>
			<th>序号</th>
			<th>书名</th>
			<th>作者</th>
			<th>出版社</th>
			<th>价格</th>
			<th>状态</th>
			<th>入馆时间</th>
			<th>借阅/归还</th>
			<th>操作</th>
		</tr>
		<c:if test="${not empty books}">
			<c:forEach items="${books}" var="book">
				<tr class="${book.status == '已借出' ? 'borrowed-book' : ''}" >
					<td><input type="checkbox" name="ck" class="select-checkbox" value="${book.id}"/></td>
					<td>${book.id}</td>
					<td>${book.bookname}</td>
					<td>${book.author}</td>
					<td>${book.introduce}</td>
					<td>${book.price}</td>
					<td>${book.status}</td>
					<td>${book.entry_time}</td>
					<td>
						<c:if test="${book.status == '可借阅'}">
							<button><a href="modifyStatusServlet?id=${book.id}" onclick="return borrowBook('${book.id}')">借阅</a></button>
						</c:if>
						<c:if test="${book.status == '已借出'}">
							<button><a href="modifyStatusServlet?id=${book.id}" onclick="return returnBook('${book.id}')">归还</a></button>
						</c:if>
					</td>
					<td>
						<button><a href="javascript:void(0)" onclick="deleteBook('${book.id}')">删除</a></button>
						<button><a href="modifyBookServlet?id=${book.id}" onclick="return confirm('确定修改吗?')">修改</a></button>
					</td>
				</tr>
			</c:forEach>
		</c:if>
	</table>
	<input type="button" value="批量删除" onclick="del()"/>
</form>

<script>
	function del() {
		if (confirm("您确定真的删除吗?")) {
			$.ajax({
				url: '/deleteByIds',
				type: 'POST',
				data: $('form').serialize(),
				success: function(response) {
					alert("删除成功!");
					location.reload();
				},
				error: function() {
					alert("删除失败,请重试。");
				}
			});
			return false; // 阻止表单提交
		}
		return false; // 取消删除
	}



	function deleteBook(bookId) {
		if (confirm("确定删除该书籍吗?")) {
			$.ajax({
				url: 'deleteBookServlet?id=' + bookId,
				type: 'POST',
				success: function(response) {
					alert("删除成功!");
					location.reload();
				},
				error: function() {
					alert("删除失败,请重试。");
				}
			});
		}
	}

	function borrowBook(bookId) {
		if (confirm("确定借阅该书籍吗?")) {
			$.ajax({
				url: 'modifyStatusServlet?id=' + bookId,
				type: 'POST',
				success: function(response) {
					alert("借阅成功!");
					location.reload();
				},
				error: function() {
					alert("借阅失败,请重试。");
				}
			});
			return false; // 阻止链接跳转
		}
		return false; // 取消借阅
	}

	function returnBook(bookId) {
		if (confirm("确定归还该书籍吗?")) {
			$.ajax({
				url: 'modifyStatusServlet?id=' + bookId,
				type: 'POST',
				success: function(response) {
					alert("归还成功!");
					location.reload();
				},
				error: function() {
					alert("归还失败,请重试。");
				}
			});
			return false;
		}
		return false;
	}

	function toggleRowHighlight(row) {
		row.classList.toggle('borrowed-book');
	}

	document.getElementById('select-all-checkbox').addEventListener('change', function() {
		var checkboxes = document.getElementsByClassName('select-checkbox');
		for (var i = 0; i < checkboxes.length; i++) {
			checkboxes[i].checked = this.checked;
		}
	});
</script>

<h4 align="center">图书总数量为:${books.length()} 件</h4>

</body>
</html>

界面展示

主页

新增

借阅
 

删除

修改

查询

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值