很久以前写过基于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>