diff --git a/RManager.md b/RManager.md deleted file mode 100644 index a04a041..0000000 --- a/RManager.md +++ /dev/null @@ -1,3051 +0,0 @@ -/* -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"); - %> - - - - - - - - - - - - - - - -