/* filter 包:Java Web 中 Filter 用于过滤请求,处理编码、权限验证、XSS 防护等。比如图中的 AdminFilter、XSSFilter,分别做权限和防攻击。 javabean 包:存放实体类,封装数据,对应数据库表或业务数据。像 Admin、Manager 这些类,用于存储属性,遵循 JavaBean 规范,有 getter/setter 等。 servlet 包:处理客户端请求,接收参数,调用业务逻辑,返回响应。比如 ManagerLogin 处理登录请求,Announcement 相关的处理公告操作。 现在组织这些内容,分三个部分解释每个包的作用,确保清晰准确。 */ /// // * * * CharacterEncondingFilter.java /** * 字符编码过滤器,用于统一设置请求与响应的字符编码为UTF-8,解决文本乱码问题 */ public class CharacterEncodingFilter implements Filter { /** * 过滤器初始化方法,由容器调用,用于获取过滤器配置参数等初始化操作 * @param filterConfig 过滤器配置对象,可从中读取初始化参数 * @throws ServletException 初始化过程中发生异常时抛出 */ public void init(FilterConfig filterConfig) throws ServletException { } /** * 执行过滤逻辑的核心方法,处理请求响应的编码设置 * @param servletRequest 客户端发送的请求对象 * @param servletResponse 服务器返回的响应对象 * @param filterChain 过滤链,用于将请求响应传递给后续处理组件 * @throws IOException 输入输出操作异常 * @throws ServletException Servlet处理过程异常 */ public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 设置请求编码为UTF-8,确保接收参数时字符编码统一 servletRequest.setCharacterEncoding("UTF-8"); // 设置响应编码为UTF-8,确保返回数据的字符编码统一 servletResponse.setCharacterEncoding("UTF-8"); // 将请求和响应传递给过滤链中的下一个组件(如其他过滤器或Servlet) filterChain.doFilter(servletRequest, servletResponse); } /** * 过滤器销毁方法,由容器调用,用于释放过滤器占用的资源 * 当前过滤器无需要释放的资源,方法体为空 */ public void destroy() { } } // * * * ManagerFilter.java package filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; // * 图书管理员过滤类,用于拦截请求并校验用户是否为登录状态的图书管理员* 实现Filter接口,完成请求过滤逻辑 public class ManagerFilter implements Filter { // * 过滤器销毁方法,用于释放资源* 在过滤器生命周期结束时调用,此处暂无资源释放操作 public void destroy() { } /** * 核心过滤方法,处理请求过滤逻辑 * @param request 客户端发送的请求对象 * @param response 服务器返回的响应对象 * @param chain 过滤器链,用于传递请求和响应 * @throws IOException IO异常 * @throws ServletException Servlet处理异常 */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 将通用请求对象转换为Http请求对象 HttpServletRequest req = (HttpServletRequest) request; // 获取请求对应的HttpSession HttpSession session = req.getSession(); // 检查session是否存在,以及session中是否存在标识管理员登录的"manager"属性 if (session == null || session.getAttribute("manager") == null) { // 将通用响应对象转换为Http响应对象 HttpServletResponse rep = (HttpServletResponse) response; // 重定向到管理员登录页面,阻止未登录用户访问受保护资源 rep.sendRedirect(req.getContextPath() + "/loginManager.html"); return; // 终止后续过滤逻辑 } // 将请求和响应传递给过滤器链中的下一个组件(如其他过滤器或Servlet) chain.doFilter(request, response); } // * 过滤器初始化方法,用于获取配置参数等初始化操作* @param fConfig 过滤器配置对象* @throws ServletException Servlet初始化异常 public void init(FilterConfig fConfig) throws ServletException { } } // * XSS过滤器,用于过滤请求参数中的跨站脚本攻击代码(如 script、style 标签等),保护应用免受 XSS 攻击 public class XSSFilter implements Filter { /** * 过滤输入字符串中的 XSS 相关代码 * @param htmlStr 待过滤的字符串 * @return 过滤后的字符串,移除了 script、style、HTML 标签内容 */ public String filter(String htmlStr) { if (htmlStr == null) { return null; } // 定义匹配 script 标签的正则表达式,不区分大小写 String regEx_script = "]*?>[\\s\\S]*?<\\/script>"; // 定义匹配 style 标签的正则表达式,不区分大小写 String regEx_style = "]*?>[\\s\\S]*?<\\/style>"; // 定义匹配 HTML 标签的正则表达式,不区分大小写 String regEx_html = "<[^>]+>"; // 编译 script 正则表达式为 Pattern 对象 Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE); Matcher m_script = p_script.matcher(htmlStr); // 替换所有匹配的 script 标签内容为空,即过滤掉 script 标签 htmlStr = m_script.replaceAll(""); // 编译 style 正则表达式为 Pattern 对象 Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE); Matcher m_style = p_style.matcher(htmlStr); // 替换所有匹配的 style 标签内容为空,即过滤掉 style 标签 htmlStr = m_style.replaceAll(""); // 编译 HTML 标签正则表达式为 Pattern 对象 Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE); Matcher m_html = p_html.matcher(htmlStr); // 替换所有匹配的 HTML 标签内容为空,即过滤掉 HTML 标签 htmlStr = m_html.replaceAll(""); return htmlStr.trim(); // 返回处理后去除首尾空白的字符串 } //自定义请求包装类,重写参数获取方法以实现 XSS 过滤 继承 HttpServletRequestWrapper,包装 HttpServletRequest 对象 class Request extends HttpServletRequestWrapper { public Request(HttpServletRequest request) { super(request); } //重写获取多个参数值的方法,对每个参数值进行 XSS 过滤 ,@param name 参数名 ,@return 过滤后的参数值数组 @Override public String getParameter(String name) { // 获取原始参数值并进行过滤 return filter(super.getRequest().getParameter(name)); } // * * * XSSFilter.java //重写获取多个参数值的方法,对每个参数值进行 XSS 过滤 ,@param name 参数名 ,@return 过滤后的参数值数组 @Override public String[] getParameterValues(String name) { // 获取原始参数值数组 String[] values = super.getRequest().getParameterValues(name); // 遍历数组,对每个参数值进行过滤 for (int i = 0; i < values.length; i++) { values[i] = filter(values[i]); } return values; } } /** * 执行过滤逻辑的核心方法 * @param request 客户端请求对象 * @param response 服务器响应对象 * @param chain 过滤链,用于传递请求和响应 * @throws IOException IO 异常 * @throws ServletException Servlet 处理异常 */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 使用自定义的 Request 包装请求,实现参数过滤 request = new Request((HttpServletRequest) request); // 将过滤后的请求传递给过滤链后续组件 chain.doFilter(request, response); } //过滤器销毁方法,用于释放资源(当前无资源释放操作) @Override public void destroy() { } } // * * * src/main/java/javabean/base.java package javabean; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * 数据库操作基础类,封装数据库连接、查询、更新和资源释放的通用方法 * 依赖DBConstants类获取数据库连接配置 */ public class Base { // 数据库连接配置(从DBConstants类获取) private static final String driver = DBConstants.driver; private static final String url = DBConstants.url; private static final String username = DBConstants.username; private static final String password = DBConstants.password; /** * 获取数据库连接 * @return 数据库连接对象 * @throws ClassNotFoundException 数据库驱动未找到异常 */ public static Connection getConnection() throws ClassNotFoundException { Connection connection = null; try { // 加载数据库驱动 Class.forName(driver); // 建立数据库连接 connection = (Connection) DriverManager.getConnection(url, username, password); } catch (SQLException e) { e.printStackTrace(); // 打印异常堆栈(实际项目建议日志记录) } return connection; } /** * 执行数据库查询操作 * @param connection 数据库连接(可复用) * @param preparedStatement 预编译语句(可复用) * @param resultSet 结果集(可复用) * @param sql SQL语句 * @param params 参数数组(用于预编译语句的占位符) * @return 查询结果集 * @throws SQLException SQL执行异常 */ public static ResultSet executequery(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet, String sql, Object[] params) throws SQLException { // 如果预编译语句为空,则创建新实例 if (preparedStatement == null) { preparedStatement = (PreparedStatement) connection.prepareStatement(sql); } // 设置预编译语句参数 for (int i = 0; params != null && i < params.length; i++) { preparedStatement.setObject(i + 1, params[i]); } // 执行查询并返回结果集 resultSet = preparedStatement.executeQuery(); return resultSet; } /** * 执行数据库更新操作(INSERT/UPDATE/DELETE) * @param connection 数据库连接(可复用) * @param preparedStatement 预编译语句(可复用) * @param sql SQL语句 * @param params 参数数组(用于预编译语句的占位符) * @return 受影响的行数 * @throws SQLException SQL执行异常 */ public static int executeUpdate(Connection connection, PreparedStatement preparedStatement, String sql, Object[] params) throws SQLException { // 如果预编译语句为空,则创建新实例 if (preparedStatement == null) { preparedStatement = (PreparedStatement) connection.prepareStatement(sql); } // 设置预编译语句参数 for (int i = 0; params != null && i < params.length; i++) { preparedStatement.setObject(i + 1, params[i]); } // 执行更新并返回受影响的行数 int updateRows = preparedStatement.executeUpdate(); return updateRows; } /** * 释放数据库资源(结果集、预编译语句、连接) * @param connection 数据库连接(可选) * @param preparedStatement 预编译语句(可选) * @param resultSet 结果集(可选) * @return 资源释放成功标志 * @throws SQLException 资源释放异常 */ public static boolean closeResource(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) throws SQLException { boolean flag = true; // 按顺序关闭资源:结果集 → 预编译语句 → 连接 if (resultSet != null) { try { resultSet.close(); resultSet = null; } catch (SQLException e) { e.printStackTrace(); flag = false; } } if (preparedStatement != null) { try { preparedStatement.close(); preparedStatement = null; } catch (SQLException e) { e.printStackTrace(); flag = false; } } if (connection != null) { try { connection.close(); connection = null; } catch (SQLException e) { e.printStackTrace(); flag = false; } } return flag; } } // * * * src/main/java/javabean/DBConstants.java package javabean; /** * 数据库连接配置类,存储数据库连接所需的常量参数 * 注意:实际项目中应避免硬编码密码,建议使用配置文件或环境变量 */ public class DBConstants { // MySQL JDBC驱动类(适用于MySQL Connector/J 8.0+版本) public static final String driver = "com.mysql.cj.jdbc.Driver"; // 数据库连接URL // 格式:jdbc:mysql://<主机>:<端口>/<数据库名>?参数 // 示例说明: // - localhost:3306:本地MySQL服务,默认端口 // - library:数据库名称 // - useSSL=false:禁用SSL连接(生产环境建议启用) // - serverTimezone=UTC:设置时区为UTC(与数据库保持一致) // - useUnicode=true&characterEncoding=UTF-8:启用Unicode编码,字符集UTF-8 public static final String url = "jdbc:mysql://localhost:3306/library?&useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8"; // 数据库用户名(通常为root或具有适当权限的用户) public static final String username = "root"; // 数据库密码(注意:硬编码密码存在安全风险,建议使用配置文件或环境变量) public static final String password = "123456"; } // * * * src/main/java/javabean/JDBCBean.java package javabean; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; /** * 数据库操作工具类,封装基本的JDBC操作(存在安全风险和性能问题,建议改进) * 注意:直接使用Statement存在SQL注入风险,建议改用PreparedStatement */ public class JDBCBean { // 数据库连接配置(从DBConstants类获取) private static final String driver = DBConstants.driver; private static final String url = DBConstants.url; private static final String username = DBConstants.username; private static final String password = DBConstants.password; // 数据库连接和操作对象 private Connection conn = null; private Statement stmt = null; /** * 构造方法:初始化数据库连接和Statement对象 * 注意:直接抛出异常到调用者,避免在构造方法中吞掉异常 * 潜在问题:每次实例化都会创建新连接,未使用连接池,影响性能 */ public JDBCBean() { try { Class.forName(driver); // 加载数据库驱动 conn = DriverManager.getConnection(url, username, password); // 建立连接 stmt = conn.createStatement(); // 创建Statement对象(存在SQL注入风险) System.out.println("成功与数据库建立连接!"); } catch (ClassNotFoundException | SQLException e) { System.out.println("无法与数据库建立连接!"); e.printStackTrace(); // 打印异常堆栈(生产环境应使用日志记录) } } /** * 执行数据库更新操作(INSERT/UPDATE/DELETE) * @param s SQL语句(存在SQL注入风险) * @return 受影响的行数 */ public int executeUpdate(String s) { int result = 0; try { System.out.println("执行SQL:" + s); // 调试输出,生产环境应移除 result = stmt.executeUpdate(s); } catch (SQLException e) { System.out.println("执行更新错误!"); e.printStackTrace(); } return result; } /** * 执行数据库查询操作 * @param s SQL语句(存在SQL注入风险) * @return 查询结果集(需要手动关闭) */ public ResultSet executeQuery(String s) { ResultSet rs = null; try { rs = stmt.executeQuery(s); } catch (SQLException e) { System.out.println("执行查询错误!" + e.getMessage()); e.printStackTrace(); } return rs; } /** * 关闭数据库资源(Statement和Connection) * 注意:未正确处理异常,可能导致资源泄漏 * 建议:使用try-with-resources或在finally块中调用 */ public void close() { try { if (stmt != null) stmt.close(); if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } // * * * src/main/java/javabean/Common.java package javabean; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.TreeMap; /** * 通用数据库操作工具类,提供表行数统计和图书馆信息映射等功能 */ public class Common { /** * 获取指定表的总记录数 * @param table 表名(不能为空) * @return 记录总数(若表不存在或查询失败返回0) * @throws ClassNotFoundException 数据库驱动未找到异常 * @throws SQLException SQL执行异常 */ public static int getCount(String table) throws SQLException, ClassNotFoundException { if (table == null || table.equals("")) { return 0; // 表名为空直接返回0 } Connection connection = null; PreparedStatement pstmt = null; ResultSet resultSet = null; try { connection = Base.getConnection(); // 获取数据库连接 // 构建查询总行数的SQL语句 pstmt = connection.prepareStatement("SELECT COUNT(*) AS count FROM " + table); resultSet = pstmt.executeQuery(); // 执行查询 resultSet.next(); // 移动到结果集第一条记录 return resultSet.getInt("count"); // 返回总记录数 } catch (SQLException e) { e.printStackTrace(); // 打印异常堆栈(实际项目建议日志记录) return 0; // 查询失败返回0 } finally { // 释放数据库资源 Base.closeResource(connection, pstmt, resultSet); } } /** * 获取所有图书馆的ID-名称映射(按ID升序排列) * @return TreeMap<图书馆ID, 图书馆名称>(若查询失败返回null) * @throws SQLException SQL执行异常 */ public static TreeMap getLibraryMap() throws SQLException { Connection connection = null; PreparedStatement libraryPstmt = null; ResultSet librarySet = null; String librarySql = "SELECT id, name FROM library"; // 查询图书馆的SQL语句 TreeMap map = new TreeMap<>(); // 使用TreeMap自动按键(ID)排序 try { connection = Base.getConnection(); // 获取数据库连接 libraryPstmt = connection.prepareStatement(librarySql); // 创建预编译语句 librarySet = libraryPstmt.executeQuery(); // 执行查询 // 遍历结果集,填充TreeMap while (librarySet.next()) { String id = librarySet.getString("id"); String name = librarySet.getString("name"); map.put(id, name); // 键为ID,值为名称 } } catch (ClassNotFoundException e) { e.printStackTrace(); return null; // 驱动未找到返回null } catch (SQLException e) { e.printStackTrace(); return null; // SQL执行失败返回null } finally { // 释放数据库资源 Base.closeResource(connection, libraryPstmt, librarySet); } return map; } /** * 测试方法(实际项目建议删除) * @param args 命令行参数 * @throws SQLException SQL执行异常 */ public static void main(String[] args) throws SQLException { System.out.println(Common.getLibraryMap()); // 打印图书馆映射 } } // * * * src/main/java/javabean/CompareDate.java package javabean; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; /** * 日期比较工具类,提供计算两个日期字符串时间差的功能 */ public class CompareDate { /** * 计算两个日期字符串之间的天数差(结束日期 - 开始日期) * @param Str1 开始日期字符串(格式:yyyy-MM-dd HH:mm:ss) * @param Str2 结束日期字符串(格式:yyyy-MM-dd HH:mm:ss) * @return 相差的天数(可能为负数,表示结束日期早于开始日期) * @throws ParseException 日期格式不正确时抛出(当前方法未处理,直接打印堆栈) * @implNote 使用SimpleDateFormat进行日期解析,存在线程不安全问题 * @implNote 时间差计算为毫秒差除以一天的毫秒数(24*60*60*1000),结果为整数天数 */ public static long show(String Str1, String Str2) { long between = 0; SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { Date date1 = format.parse(Str1); // 解析开始日期 Date date2 = format.parse(Str2); // 解析结束日期 between = date2.getTime() - date1.getTime(); // 计算时间差(毫秒) } catch (ParseException e) { e.printStackTrace(); // 打印异常堆栈(实际项目应处理异常) } // 转换为天数(注意:直接除以一天的毫秒数可能导致精度丢失) long days = between / (24 * 60 * 60 * 1000); return days; } // 示例用法 public static void main(String[] args) { long days = CompareDate.show("2023-01-01 00:00:00", "2023-01-03 23:59:59"); System.out.println("相差天数:" + days); // 输出:2 } } // * * * Manager.java package javabean; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * 管理员业务逻辑处理类,封装管理员登录验证功能 */ public class Manager { /** * 管理员登录验证方法 * @param user 管理员账号 * @param psw 管理员密码 * @return 验证结果:"1"表示成功,其他字符串表示失败原因 * @throws ClassNotFoundException 数据库驱动未找到异常 * @throws SQLException 数据库操作异常 */ @SuppressWarnings("null") // 抑制空指针警告(resultSet在finally中已关闭) public String login(String user, String psw) throws ClassNotFoundException, SQLException { // 参数校验 if (user == null || user.trim().equals("")) { return "账号不能为空"; } else if (psw == null || psw.trim().equals("")) { return "密码不能为空"; } Connection connection = null; PreparedStatement pstmt = null; ResultSet resultSet = null; String sql = "select * from manager where ACCOUNT=? and PASSWORD=?"; try { connection = Base.getConnection(); // 获取数据库连接 pstmt = connection.prepareStatement(sql); // 预编译SQL pstmt.setString(1, user); // 绑定账号参数 pstmt.setString(2, psw); // 绑定密码参数 resultSet = pstmt.executeQuery(); // 执行查询 if (resultSet.next()) { // 若存在匹配记录 return "1"; // 返回成功标识 } return "账号或密码错误"; // 查询无结果时返回错误信息 } finally { // 释放数据库资源 Base.closeResource(connection, pstmt, resultSet); } } } // * * * java/servlet/announcement.java package servlet.manager; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; 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 javabean.Base; import javabean.Util; import net.sf.json.JSONArray; import net.sf.json.JSONObject; /** * 公告管理Servlet,处理公告查询请求 * 映射路径:/manager/announcement * 仅响应GET请求,返回公告列表的JSON数据 */ @WebServlet("/manager/announcement") public class Announcement extends HttpServlet { /** * 处理GET请求,查询公告列表并返回JSON数据 * @param req HTTP请求对象 * @param resp HTTP响应对象 * @throws ServletException Servlet处理异常 * @throws IOException IO异常 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置响应格式为JSON,字符集UTF-8 resp.setContentType("application/json; charset=utf8"); // 数据库操作变量 Connection connection = null; PreparedStatement pstmt = null; String sql = ""; ResultSet resultSet = null; // 响应数据 int code = 1; // 状态码:1=失败,0=成功 String msg = "无数据"; // 状态描述 JSONObject jsonObject = new JSONObject(); // 单条公告JSON对象 JSONArray jsonArray = new JSONArray(); // 公告列表JSON数组 try { // 获取数据库连接 connection = Base.getConnection(); // 查询所有公告的SQL语句 sql = "select * from announcement"; pstmt = connection.prepareStatement(sql); resultSet = pstmt.executeQuery(); // 遍历结果集,封装为JSON格式 while (resultSet.next()) { jsonObject.put("id", resultSet.getString("id")); // 公告ID jsonObject.put("title", resultSet.getString("title")); // 公告标题 jsonObject.put("detail", resultSet.getString("detail")); // 公告详情 jsonObject.put("publish_date", resultSet.getString("publish_date")); // 发布日期 jsonArray.add(jsonObject); // 添加到公告列表 } // 根据查询结果设置响应状态 if (!jsonArray.isEmpty()) { code = 0; msg = "查询成功"; } else { msg = "数据为空"; } } catch (ClassNotFoundException e) { msg = "数据库驱动未找到"; } catch (SQLException e) { msg = "SQL执行错误"; } finally { // 释放数据库资源 try { Base.closeResource(connection, pstmt, resultSet); } catch (SQLException e) { msg = "资源释放失败"; } } // 生成最终响应JSON PrintWriter out = resp.getWriter(); out.print(Util.jsonResponse(code, msg, jsonArray.toString())); } } // * * * java/servlet/announcementAdd.java package servlet.manager; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; 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 javabean.Base; import javabean.DateTime; import net.sf.json.JSONArray; import net.sf.json.JSONObject; /** * 公告添加Servlet,处理公告发布请求 * 映射路径:/manager/announcementAdd * 仅响应POST请求,接收公告标题、内容并保存到数据库 */ @WebServlet("/manager/announcementAdd") public class AnnouncementAdd extends HttpServlet { /** * 处理POST请求,接收公告信息并插入数据库 * @param req HTTP请求对象(包含公告标题、内容参数) * @param resp HTTP响应对象(返回操作结果JSON) * @throws ServletException Servlet处理异常 * @throws IOException IO异常 */ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置响应格式为JSON,字符集UTF-8 resp.setContentType("application/json; charset=utf8"); // 接收客户端提交的参数 String id = req.getParameter("id"); // 未使用的参数(可能为测试保留) String tit = req.getParameter("title"); // 公告标题 String det = req.getParameter("detail"); // 公告内容 DateTime date = new DateTime(); // 获取当前时间 String time = date.show(); // 格式化时间字符串 // 数据库操作变量 Connection connection = null; PreparedStatement pstmt = null; ResultSet resultSet = null; int result = 0; // 数据库操作影响的行数 int count = 0; // 未使用的计数器(可能为测试保留) // 响应数据 int code = 1; // 状态码:1=失败,0=成功 String msg = ""; // 状态描述 JSONArray jsonArray = new JSONArray(); // 未使用的JSON数组(可能为测试保留) JSONObject json = new JSONObject(); // 响应结果JSON对象 // SQL语句:插入公告信息(注意:id字段未包含,由数据库自增) String sql = "insert into announcement(title, detail, publish_date) values(?,?,?)"; System.out.println(sql); // 控制台打印SQL语句(生产环境建议移除) PrintWriter out = resp.getWriter(); // 获取响应输出流 try { // 获取数据库连接 connection = Base.getConnection(); // 预编译SQL语句 pstmt = connection.prepareStatement(sql); // 绑定参数:标题、内容、发布时间 pstmt.setString(1, tit); pstmt.setString(2, det); pstmt.setString(3, time); // 执行插入操作 result = pstmt.executeUpdate(); } catch (SQLException e) { // 捕获SQL异常(未处理具体错误信息,建议添加日志) } catch (ClassNotFoundException e) { e.printStackTrace(); // 打印驱动未找到异常堆栈 } finally { // 释放数据库资源(结果集为null,无需关闭) try { Base.closeResource(connection, pstmt, null); } catch (SQLException e) { e.printStackTrace(); // 打印资源释放异常堆栈 } } // 根据操作结果生成响应JSON if (result == 1) { json.put("code", "0"); json.put("msg", "success"); } else { json.put("code", "1"); json.put("msg", "error"); } out.write(json.toString()); // 输出响应结果 } } // * * * java/servlet/announcementDel.java package servlet.manager; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; 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 javabean.Base; import javabean.Util; /** * 公告删除Servlet,处理公告删除请求 * 映射路径:/manager/announcementDel * 仅响应GET请求,根据公告ID执行删除操作 */ @WebServlet("/manager/announcementDel") public class AnnouncementDel extends HttpServlet { /** * 处理GET请求,根据ID删除公告并返回JSON响应 * @param req HTTP请求对象(包含公告ID参数id) * @param resp HTTP响应对象(返回删除结果JSON) * @throws ServletException Servlet处理异常 * @throws IOException IO异常 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取请求参数:公告ID String id = req.getParameter("id"); // 数据库操作变量 String sql = ""; // SQL语句 Connection connection = null; // 数据库连接 PreparedStatement pstmt = null; // 预编译语句 ResultSet resultSet = null; // 结果集(未使用) int result = 0; // 数据库操作影响的行数 // 响应数据 int code = 1; // 状态码:1=失败,0=成功 String msg = ""; // 状态描述 PrintWriter out = resp.getWriter(); // 响应输出流 try { // 获取数据库连接 connection = Base.getConnection(); // 预编译删除SQL,使用占位符?防止SQL注入 sql = "delete from announcement where id=?"; pstmt = connection.prepareStatement(sql); // 绑定参数:公告ID pstmt.setString(1, id); // 执行删除操作 result = pstmt.executeUpdate(); // 根据影响的行数判断操作结果 if (result == 1) { code = 0; msg = "删除成功"; } else { msg = "删除失败(ID不存在或操作异常)"; } } catch (ClassNotFoundException e) { msg = "数据库驱动未找到"; } catch (SQLException e) { msg = "SQL执行错误:" + e.getMessage(); // 建议记录详细错误日志 } finally { // 释放数据库资源 try { Base.closeResource(connection, pstmt, resultSet); } catch (SQLException e) { e.printStackTrace(); // 打印资源释放异常堆栈 } } // 生成JSON响应:状态码、消息、空数据 out.print(Util.jsonResponse(code, msg, null)); } } // * * * java/servlet/announcementEdit.java package servlet.manager; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; 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 javabean.Base; import javabean.Util; import net.sf.json.JSONArray; import net.sf.json.JSONObject; /** * 公告编辑Servlet,处理公告内容修改请求 * 映射路径:/manager/announcementEdit * 仅响应POST请求,接收公告ID、新标题和内容并更新数据库 */ @WebServlet("/manager/announcementEdit") public class AnnouncementEdit extends HttpServlet { /** * 处理POST请求,执行公告内容修改并返回JSON响应 * @param req HTTP请求对象(包含公告ID、新标题和内容参数) * @param resp HTTP响应对象(返回操作结果JSON) * @throws ServletException Servlet处理异常 * @throws IOException IO异常 */ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置响应格式为JSON,字符集UTF-8 resp.setContentType("application/json; charset=utf8"); // 接收客户端提交的参数 String id = req.getParameter("id"); // 公告ID(未校验非空) String tit = req.getParameter("title"); // 新公告标题 String det = req.getParameter("detail"); // 新公告内容 // 数据库操作变量 String sql = ""; // SQL语句 Connection connection = null; // 数据库连接 PreparedStatement pstmt = null; // 预编译语句 ResultSet resultSet = null; // 结果集(未使用) int result = 0; // 数据库操作影响的行数 // 响应数据 int code = 1; // 状态码:1=失败,0=成功 String msg = ""; // 状态描述 PrintWriter out = resp.getWriter(); // 响应输出流 JSONArray jsonArray = new JSONArray(); // 未使用的JSON数组(建议删除) JSONObject jsonObject = new JSONObject(); // 未使用的JSON对象(建议删除) // 参数校验:标题和内容不能为空 if (tit == null || tit.equals("") || det == null || det.equals("")) { msg = "参数不能为空"; out.print(Util.jsonResponse(code, msg, null)); return; // 终止后续处理 } try { // 获取数据库连接 connection = Base.getConnection(); // 预编译更新SQL,使用占位符?防止SQL注入 sql = "update announcement set title=?, detail=? where id=?"; pstmt = connection.prepareStatement(sql); // 绑定参数:新标题、新内容、公告ID pstmt.setString(1, tit); pstmt.setString(2, det); pstmt.setString(3, id); // 执行更新操作 result = pstmt.executeUpdate(); // 根据影响的行数判断操作结果 if (result == 1) { code = 0; msg = "修改成功"; } else { msg = "修改失败(ID不存在或操作异常)"; } } catch (ClassNotFoundException e) { msg = "数据库驱动未找到"; } catch (SQLException e) { msg = "SQL执行错误:" + e.getMessage(); // 建议记录详细错误日志 } finally { // 释放数据库资源 try { Base.closeResource(connection, pstmt, resultSet); } catch (SQLException e) { e.printStackTrace(); // 打印资源释放异常堆栈 } } // 生成JSON响应:状态码、消息、空数据 out.print(Util.jsonResponse(code, msg, null)); } } // * * * java/servlet/BorrowTable.java package servlet.manager; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; 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 javabean.Base; import net.sf.json.JSONArray; import net.sf.json.JSONObject; /** * 借阅记录管理Servlet,处理分页查询和条件过滤请求 * 映射路径:/manager/borrowTable * 仅响应GET请求,返回符合条件的借阅记录列表(JSON格式) */ @WebServlet("/manager/borrowTable") public class BorrowTable extends HttpServlet { /** * 处理GET请求,执行分页查询并返回JSON数据 * @param req HTTP请求对象(包含分页参数和过滤条件) * @param resp HTTP响应对象(返回查询结果JSON) * @throws ServletException Servlet处理异常 * @throws IOException IO异常 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置响应格式为JSON,字符集UTF-8 resp.setContentType("application/json; charset=utf8"); // 接收客户端参数 String limit = req.getParameter("limit"); // 每页显示数量 String page = req.getParameter("page"); // 当前页码 String condition = req.getParameter("condition"); // 过滤字段(如card_id) String conditionValue = req.getParameter("conditionValue"); // 过滤值 // 初始化查询条件 String where = ""; // 无限制条件 if (page == null) page = "1"; // 默认页码1 if (limit == null) limit = "10"; // 默认每页10条 // 数据库操作变量 Connection connection = null; PreparedStatement pstmt = null; // 数据查询语句 PreparedStatement countPstmt = null; // 总数查询语句 ResultSet resultSet = null; ResultSet countSet = null; String sql = ""; String countSql = ""; // 响应数据 int code = 1; // 状态码:1=失败,0=成功 String msg = "无数据"; // 状态描述 int count = 0; // 总记录数 JSONObject jsonData = new JSONObject(); // 单条记录JSON对象 JSONArray jsonArray = new JSONArray(); // 记录列表JSON数组 JSONObject jsonResult = new JSONObject(); // 最终响应JSON try { // 获取数据库连接 connection = Base.getConnection(); // 构建基础查询SQL(过滤manager_id不为null的记录) sql = "select * from borrow_books where manager_id is not null"; // 拼接条件查询(注意:直接拼接字符串存在SQL注入风险) if (condition != null && conditionValue != null && !condition.equals("") && !conditionValue.equals("")) { where = " and " + condition + " like '%" + conditionValue + "%' "; sql += where; } // 拼接分页参数(使用预编译占位符) sql += " limit ?,?"; System.out.println("查询SQL:" + sql); // 调试用,生产环境建议移除 // 执行数据查询 pstmt = connection.prepareStatement(sql); // 计算分页偏移量:(当前页-1)*每页数量 pstmt.setInt(1, (Integer.parseInt(page) - 1) * Integer.parseInt(limit)); pstmt.setInt(2, Integer.parseInt(limit)); resultSet = pstmt.executeQuery(); // 封装查询结果为JSON while (resultSet.next()) { jsonData.put("id", resultSet.getString("id")); // 记录ID jsonData.put("card_id", resultSet.getString("card_id")); // 读者卡号 jsonData.put("book_id", resultSet.getString("book_id")); // 图书ID jsonData.put("borrow_date", resultSet.getString("borrow_date")); // 借阅日期 jsonData.put("end_date", resultSet.getString("end_date")); // 应还日期 jsonData.put("return_date", resultSet.getString("return_date")); // 归还日期 jsonData.put("illegal", resultSet.getString("illegal")); // 违规状态 jsonData.put("manager_id", resultSet.getString("manager_id")); // 管理员ID jsonArray.add(jsonData); // 添加到记录列表 } // 执行总记录数查询 countSql = "select count(*) as count from borrow_books where manager_id is not null" + where; countPstmt = connection.prepareStatement(countSql); countSet = countPstmt.executeQuery(); if (countSet.next()) { count = countSet.getInt("count"); // 获取总记录数 } // 设置响应状态 if (!jsonArray.isEmpty()) { code = 0; msg = "查询成功"; } } catch (ClassNotFoundException e) { msg = "数据库驱动未找到"; } catch (SQLException e) { msg = "SQL执行错误:" + e.getMessage(); } finally { // 分批次释放资源 try { Base.closeResource(null, pstmt, resultSet); // 关闭数据查询资源 Base.closeResource(connection, countPstmt, countSet); // 关闭总数查询资源 } catch (SQLException e) { msg = "资源释放失败"; } } // 构建最终响应JSON jsonResult.put("code", code); jsonResult.put("count", count); jsonResult.put("msg", msg); jsonResult.put("data", jsonArray.toArray()); // 转换为JSON数组 // 输出响应 PrintWriter out = resp.getWriter(); out.print(jsonResult.toString()); } } // * * * java/servlet/ManagerLogin.java package servlet.manager; import java.io.IOException; import java.io.PrintWriter; import java.sql.SQLException; import java.util.HashMap; 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 javabean.Manager; import net.sf.json.JSONObject; /** * 管理员登录Servlet,处理管理员登录请求 * 映射路径:/managerLogin * 仅响应POST请求,验证账号密码并返回登录结果 */ @WebServlet("/managerLogin") public class ManagerLogin extends HttpServlet { /** * 处理GET请求(未使用,返回简单提示) * @param request HTTP请求对象 * @param response HTTP响应对象 * @throws ServletException Servlet处理异常 * @throws IOException IO异常 */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().append("Served at: ").append(request.getContextPath()); } /** * 处理POST请求,执行管理员登录验证 * @param request HTTP请求对象(包含user和psw参数) * @param response HTTP响应对象(返回JSON格式的登录结果) * @throws ServletException Servlet处理异常 * @throws IOException IO异常 */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置响应格式为JSON,字符集UTF-8 response.setContentType("application/json; charset=utf8"); PrintWriter out = response.getWriter(); // 获取客户端提交的账号和密码 String user = request.getParameter("user"); // 管理员账号 String psw = request.getParameter("psw"); // 管理员密码 // 响应数据容器 HashMap hashMap = new HashMap<>(); // 调用业务逻辑层验证登录 Manager manager = new Manager(); String result = null; try { result = manager.login(user, psw); // 调用Manager类的登录方法 } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); // 打印数据库相关异常堆栈(生产环境建议日志记录) } // 根据验证结果生成响应 if (result.equals("1")) { // 登录成功 HttpSession session = request.getSession(); session.setAttribute("manager", user); // 记录登录用户 session.setAttribute("manager_first", "1"); // 标记首次登录状态 hashMap.put("code", 0); hashMap.put("msg", "登录成功"); // 返回跳转URL(前端根据此字段进行页面跳转) hashMap.put("url", request.getContextPath() + "/manager/01nav.jsp"); } else { // 登录失败 hashMap.put("code", 1); hashMap.put("msg", result); // 错误信息直接来自业务层 } // 将响应数据转换为JSON并输出 JSONObject json = JSONObject.fromObject(hashMap); out.write(json.toString()); } } // * * * java/servlet/Quit.java package servlet.manager; import java.io.IOException; 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; /** * 管理员退出Servlet,处理管理员注销请求 * 映射路径:/manager/quit * 仅响应GET请求,销毁用户会话并重定向到登录页面 */ @WebServlet("/manager/quit") public class Quit extends HttpServlet { private static final long serialVersionUID = 1L; /** * 处理GET请求,执行管理员退出逻辑 * @param req HTTP请求对象 * @param resp HTTP响应对象 * @throws ServletException Servlet处理异常 * @throws IOException IO异常 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取当前会话 HttpSession session = req.getSession(); // 检查会话中是否存在管理员登录标识 if (session.getAttribute("manager") != null) { // 移除登录状态,终止会话 session.removeAttribute("manager"); } // 重定向到管理员登录页面 resp.sendRedirect(req.getContextPath() + "/loginManager.html"); } } // * * * java/servlet/ReturnTable.java package servlet.manager; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; 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 javabean.Base; import net.sf.json.JSONArray; import net.sf.json.JSONObject; /** * 待归还图书管理Servlet,处理分页查询和条件过滤请求 * 映射路径:/manager/returnTable * 仅响应GET请求,返回未处理的借阅记录列表(JSON格式) */ @WebServlet("/manager/returnTable") public class ReturnTable extends HttpServlet { /** * 处理GET请求,执行分页查询并返回JSON数据 * @param req HTTP请求对象(包含分页参数和过滤条件) * @param resp HTTP响应对象(返回查询结果JSON) * @throws ServletException Servlet处理异常 * @throws IOException IO异常 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置响应格式为JSON,字符集UTF-8 resp.setContentType("application/json; charset=utf8"); // 接收客户端参数 String limit = req.getParameter("limit"); // 每页显示数量 String page = req.getParameter("page"); // 当前页码 String condition = req.getParameter("condition"); // 过滤字段(如card_id) String conditionValue = req.getParameter("conditionValue"); // 过滤值 // 初始化查询条件 String where = ""; // 无限制条件 if (page == null) page = "1"; // 默认页码1 if (limit == null) limit = "10"; // 默认每页10条 // 数据库操作变量 Connection connection = null; PreparedStatement pstmt = null; // 数据查询语句 PreparedStatement countPstmt = null; // 总数查询语句 ResultSet resultSet = null; ResultSet countSet = null; String sql = ""; String countSql = ""; // 响应数据 int code = 1; // 状态码:1=失败,0=成功 String msg = "无数据"; // 状态描述 int count = 0; // 总记录数 JSONObject jsonData = new JSONObject(); // 单条记录JSON对象 JSONArray jsonArray = new JSONArray(); // 记录列表JSON数组 JSONObject jsonResult = new JSONObject(); // 最终响应JSON try { // 获取数据库连接 connection = Base.getConnection(); // 构建基础查询SQL(过滤manager_id为null的记录) sql = "select * from borrow_books where manager_id is null"; // 拼接条件查询(注意:直接拼接字符串存在SQL注入风险) if (condition != null && conditionValue != null && !condition.equals("") && !conditionValue.equals("")) { where = " and " + condition + " like '%" + conditionValue + "%' "; sql += where; } // 拼接分页参数(使用预编译占位符) sql += " limit ?,?"; System.out.println("查询SQL:" + sql); // 调试用,生产环境建议移除 // 执行数据查询 pstmt = connection.prepareStatement(sql); // 计算分页偏移量:(当前页-1)*每页数量 pstmt.setInt(1, (Integer.parseInt(page) - 1) * Integer.parseInt(limit)); pstmt.setInt(2, Integer.parseInt(limit)); resultSet = pstmt.executeQuery(); // 封装查询结果为JSON while (resultSet.next()) { jsonData.put("id", resultSet.getString("id")); // 记录ID jsonData.put("card_id", resultSet.getString("card_id")); // 读者卡号 jsonData.put("book_id", resultSet.getString("book_id")); // 图书ID jsonData.put("borrow_date", resultSet.getString("borrow_date")); // 借阅日期 jsonData.put("end_date", resultSet.getString("end_date")); // 应还日期 jsonArray.add(jsonData); // 添加到记录列表 } // 执行总记录数查询 countSql = "select count(*) as count from borrow_books where manager_id is null" + where; countPstmt = connection.prepareStatement(countSql); countSet = countPstmt.executeQuery(); if (countSet.next()) { count = countSet.getInt("count"); // 获取总记录数 } // 设置响应状态 if (!jsonArray.isEmpty()) { code = 0; msg = "查询成功"; } } catch (ClassNotFoundException e) { msg = "数据库驱动未找到"; } catch (SQLException e) { msg = "SQL执行错误:" + e.getMessage(); } finally { // 分批次释放资源 try { Base.closeResource(null, pstmt, resultSet); // 关闭数据查询资源 Base.closeResource(connection, countPstmt, countSet); // 关闭总数查询资源 } catch (SQLException e) { msg = "资源释放失败"; } } // 构建最终响应JSON jsonResult.put("code", code); jsonResult.put("count", count); jsonResult.put("msg", msg); jsonResult.put("data", jsonArray.toArray()); // 转换为JSON数组 // 输出响应 PrintWriter out = resp.getWriter(); out.print(jsonResult.toString()); } /** * 处理POST请求(未使用) * @param request HTTP请求对象 * @param response HTTP响应对象 * @throws ServletException Servlet处理异常 * @throws IOException IO异常 */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 未实现POST逻辑 } } // * * * 前端页面 jsp // * * * 01nav.jsp // * * 02borrow.jsp 借阅图书

借阅图书

// * * * 03borrowSus.jsp 借阅图书处理 <% // 获取表单提交参数 String user = request.getParameter("userid"); // 借阅证号 String book = request.getParameter("bookid"); // 图书编号 String date1 = request.getParameter("date1"); // 借阅日期 // 查询借阅证信息 String sql1 = "select * from borrow_card where ID =" + user; ResultSet rs1 = borrow.executeQuery(sql1); // 管理员登录验证 if (session.getAttribute("manager") != null) { if (rs1.next()) { // 获取借阅证状态和规则ID String rule = rs1.getString("rule_id"); int cardstatus = Integer.parseInt(rs1.getString("STATUS")); // 查询借阅规则 String sql4 = "select * from rules where id = " + rule; ResultSet rs4 = borrow.executeQuery(sql4); int n = 0; // 借阅天数 String library = ""; // 可借阅图书馆 String[] libraryArray = {}; int num = 0; // 最大借阅数量 while (rs4.next()) { n = rs4.getInt("limit_day"); library = rs4.getString("borrow_library"); libraryArray = library.split("、"); num = rs4.getInt("borrow_num"); } // 计算应还日期 EndTime endtime = new EndTime(); String end = endtime.show(n); // 借阅证状态检查 if (cardstatus != 0) { // 查询图书信息 String sql2 = "select * from books where ID =" + book; ResultSet rs2 = borrow.executeQuery(sql2); if (rs2.next()) { int status = Integer.parseInt(rs2.getString("STATUS")); // 图书状态 String lib = Integer.toString(rs2.getInt("library_id")); // 图书所在图书馆 // 检查图书是否在可借阅图书馆列表 boolean validLibrary = false; for (int z = 0; z < libraryArray.length; z++) { if (libraryArray[z].equals(lib)) { validLibrary = true; // 查询当前用户未处理的借阅数量 String countSql = "select count(*) as count from borrow_books where manager_id is null and card_id =" + user; ResultSet rsSql = borrow.executeQuery(countSql); int count = 0; while (rsSql.next()) { count = rsSql.getInt("count"); } // 检查借阅数量限制 if (count < num) { if (status == 1) { // 图书可用 // 执行借阅操作 String sql = "insert borrow_books(CARD_ID,BOOK_ID,BORROW_DATE,END_DATE) values('" + user + "','" + book + "','" + date1 + "','" + end + "')"; try { int i = borrow.executeUpdate(sql); if (i == 1) { // 更新图书状态为已借出 borrow.executeUpdate("update books set STATUS=0 where ID=" + book); %> <% } else { %> <% } } catch (Exception e) { %> <% } } else { %> <% } } else { %> <% } break; } } // 图书馆权限检查失败 if (!validLibrary) { %> <% } } else { %> <% } } else { %> <% } } else { %> <% } } else { %> <% } %> // * * * 04judge.jsp 查询图书是否逾期

查询图书是否逾期

// * * * 04judgeSus.jsp 图书逾期查询处理 <% // 获取表单提交的图书编号 String book = request.getParameter("bookid"); session.setAttribute("book", book); // 将会话保存到session // 管理员登录验证 if (session.getAttribute("manager") != null) { DateTime date = new DateTime(); String now = date.show(); // 获取当前时间 String bookid = request.getParameter("bookid"); // 查询该图书的借阅记录 String sql = "select * from borrow_books where book_id = " + bookid; ResultSet rs = judge.executeQuery(sql); String end = ""; // 应还日期 String ret = ""; // 归还日期 String card = ""; // 借阅证号 while (rs.next()) { end = rs.getString("end_date"); ret = rs.getString("return_date"); card = rs.getString("card_id"); } if (ret == null) { // 图书未归还 // 计算逾期天数(now与end的时间差) long n = CompareDate.show(now, end); session.setAttribute("days", n); // 保存逾期天数 // 查询借阅证规则 String sql1 = "select * from borrow_card where id = " + card; ResultSet rs1 = judge.executeQuery(sql1); String rule = ""; while (rs1.next()) { rule = rs1.getString("rule_id"); } // 查询逾期费用规则 String sql2 = "select * from rules where id = " + rule; ResultSet rs2 = judge.executeQuery(sql2); String fee = ""; while (rs2.next()) { fee = rs2.getString("overtime_fee"); } session.setAttribute("fee", fee); // 保存逾期费用 // 跳转到图书归还页面 %> <% } else { // 图书已归还 %> <% } } else { // 未登录处理 %> <% } %> // * * * 04return.jsp 归还图书

归还图书

<% // 从会话中获取逾期天数、罚款金额和图书编号 Object days = session.getAttribute("days"); Object fee = session.getAttribute("fee"); String book = session.getAttribute("book").toString(); // 初始化提示信息 String mes = ""; String mes2 = ""; float sum = 0; // 根据逾期天数计算罚款 if (days != null && fee != null) { int d = Integer.parseInt(days.toString()); float f = Float.parseFloat(fee.toString()); if (d < 0) { mes = "已逾期 " + (-d) + " 天"; sum = d * f * (-1); // 计算罚款总额 mes2 = "罚款金额:¥" + sum; } else { mes = "还剩 " + d + " 天"; } // 将提示信息保存到会话中 session.setAttribute("mes", mes); session.setAttribute("mes2", mes2); } %>
<%= session.getAttribute("mes") %>
<%= session.getAttribute("mes2") %>
" autocomplete="off" class="layui-input">
<% // 查询该图书的借阅记录(未归还) String sql2 = "select * from borrow_books where return_date is null and book_id = " + book; ResultSet rs2 = judge.executeQuery(sql2); String endDate = ""; while (rs2.next()) { endDate = rs2.getString("end_date"); %>
<% } %>
">
// * * * 05returnSus.jsp 图书归还处理 <% // 获取表单提交参数 String book = request.getParameter("bookid"); // 图书编号 String date1 = request.getParameter("date1"); // 归还日期 String ill = request.getParameter("ill"); // 违规信息(可选) String managerid = request.getParameter("managerid"); // 管理员编号 // 管理员登录验证 if (session.getAttribute("manager") != null) { try { // 查询图书当前状态 String sql2 = "select * from books where ID = " + book; ResultSet rs2 = ret.executeQuery(sql2); if (rs2.next()) { int status = Integer.parseInt(rs2.getString("STATUS")); // 图书状态检查(0表示已借出,1表示可借阅) if (status == 0) { // 更新借阅记录:设置归还日期、违规信息和处理管理员 String sql = "update borrow_books " + "set RETURN_DATE = ?, ILLEGAL = ?, MANAGER_ID = ? " + "where manager_id is null and BOOK_ID = ?"; // 执行更新操作 int i = ret.executeUpdate(sql, new Object[]{date1, ill, managerid, book}); // 更新图书状态为可借阅 ret.executeUpdate("update books set STATUS = 1 where ID = ?", new Object[]{book}); %> <% } else { %> <% } } } catch (SQLException e) { e.printStackTrace(); %> <% } } else { %> <% } %> //* * * 06borrwoTable.jsp 借阅记录
//* * * 07returnTable.jsp 待归还图书列表
//* * * 08add.jsp 发布公告
required autocomplete="off" placeholder="请输入标题" class="layui-input">
//* * *08edit.jsp 公告编辑 <% // 获取URL参数中的公告ID String id = request.getParameter("id"); // 数据库操作 Connection connection = null; PreparedStatement pstmt = null; ResultSet resultSet = null; try { connection = Base.getConnection(); // 使用预编译语句查询公告信息 String sql = "select * from announcement where id=?"; pstmt = connection.prepareStatement(sql); pstmt.setString(1, id); resultSet = pstmt.executeQuery(); // 移动到结果集第一条记录 if (resultSet.next()) { // 页面后续会使用这些数据 } } catch (SQLException e) { e.printStackTrace(); } finally { // 释放资源(此处未正确关闭,建议在finally中处理) } %>
" lay-verify="required" required autocomplete="off" placeholder="请输入标题" class="layui-input">
" lay-verify="required" placeholder="请输入公告" autocomplete="off" class="layui-input">
//* * *09managerSelf.jsp 管理员个人资料
管理员基本信息
<% // 获取当前登录管理员账号 String manacc = session.getAttribute("manager").toString(); // 查询管理员信息(存在SQL注入风险!) String sql = "select * from manager where ACCOUNT = '" + manacc + "';"; ResultSet rs = gly.executeQuery(sql); while (rs.next()) { %>

姓名:<%= rs.getString("name") %>


账号:<%= rs.getString("account") %>


邮箱:<%= rs.getString("email") %>


<% } %>
//* * *updateManager.jsp 管理员资料修改处理 <% // 获取表单提交的参数 String psw1 = request.getParameter("psw1"); // 新密码 String psw2 = request.getParameter("psw2"); // 确认密码 String email1 = request.getParameter("email1"); // 新邮箱 String email2 = request.getParameter("email2"); // 确认邮箱 String name1 = request.getParameter("name1"); // 新姓名 String name2 = request.getParameter("name2"); // 确认姓名 // 获取当前登录管理员账号 String id = session.getAttribute("manager").toString(); // 密码修改逻辑 if (psw1 != null && psw2 != null) { // 验证密码一致性和非空 if (psw1.equals(psw2) && !psw1.trim().isEmpty() && !psw2.trim().isEmpty()) { // 存在SQL注入风险!建议使用预编译语句 String sql = "update manager set PASSWORD = ? where ACCOUNT = ?"; try (Connection conn = check.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, psw1); pstmt.setString(2, id); int affectedRows = pstmt.executeUpdate(); if (affectedRows == 1) { %> <% } else { %> <% } } catch (SQLException e) { e.printStackTrace(); %> <% } } else { %> <% } } // 邮箱修改逻辑 else if (email1 != null && email2 != null) { // 验证邮箱一致性和非空 if (email1.equals(email2) && !email1.trim().isEmpty() && !email2.trim().isEmpty()) { // 建议添加邮箱格式验证(正则表达式) String sql = "update manager set EMAIL = ? where ACCOUNT = ?"; try (Connection conn = check.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, email1); pstmt.setString(2, id); int affectedRows = pstmt.executeUpdate(); if (affectedRows == 1) { %> <% } else { %> <% } } catch (SQLException e) { e.printStackTrace(); %> <% } } else { %> <% } } // 姓名修改逻辑 else if (name1 != null && name2 != null) { // 验证姓名一致性和非空 if (name1.equals(name2) && !name1.trim().isEmpty() && !name2.trim().isEmpty()) { String sql = "update manager set NAME = ? where ACCOUNT = ?"; try (Connection conn = check.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, name1); pstmt.setString(2, id); int affectedRows = pstmt.executeUpdate(); if (affectedRows == 1) { %> <% } else { %> <% } } catch (SQLException e) { e.printStackTrace(); %> <% } } else { %> <% } } else { %> <% } %> // * * * loginManager.html 图书管理员登录页面

工作人员登录

// * * * src/main/webapp/index.jsp Insert title here <% // 使用response.sendRedirect方法将页面重定向到指定的URL // 这里将页面重定向到名为04readerFrame.jsp的页面,该页面位于reader目录下 response.sendRedirect("./reader/04readerFrame.jsp"); %>