122 KiB
/* 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 = "<script[^>]?>[\s\S]?<\/script>"; // 定义匹配 style 标签的正则表达式,不区分大小写 String regEx_style = "<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<String, String> getLibraryMap() throws SQLException { Connection connection = null; PreparedStatement libraryPstmt = null; ResultSet librarySet = null; String librarySql = "SELECT id, name FROM library"; // 查询图书馆的SQL语句
TreeMap<String, String> 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 时间差计算为毫秒差除以一天的毫秒数(246060*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<String, Object> 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
<!-- 头部导航区域 -->
<div class="layui-header">
<div class="layui-logo">图书馆管理人员页面</div>
<!-- 左侧导航菜单 -->
<ul class="layui-nav layui-layout-left">
<li class="layui-nav-item">
<a href="javascript:;">其它系统</a>
<dl class="layui-nav-child">
<!-- 跳转到读者系统首页 -->
<dd><a href="../reader/04readerFrame.jsp" target="parent">图书馆首页</a></dd>
<!-- 跳转到系统管理员登录页面 -->
<dd><a href="../adminLogin.html" target="parent">系统管理员</a></dd>
</dl>
</li>
</ul>
<!-- 右侧用户信息和退出 -->
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item">
<a href="javascript:;">
<!-- 显示当前登录管理员用户名 -->
<%=session.getAttribute("manager") %>
</a>
<dl class="layui-nav-child">
<!-- 跳转到管理员个人资料页面 -->
<dd><a href="09managerSelf.jsp" target="content">基本资料</a></dd>
</dl>
</li>
<!-- 退出系统 -->
<li class="layui-nav-item"><a href="./quit" target="_parent">退出</a></li>
</ul>
</div>
<!-- 左侧功能菜单 -->
<div class="layui-side layui-bg-black">
<div class="layui-side-scroll">
<ul class="layui-nav layui-nav-tree" lay-filter="test">
<!-- 图书管理模块 -->
<li class="layui-nav-item layui-nav-itemed">
<a href="javascript:;">
<i class="layui-icon layui-icon-read" style="font-size: 20px; color: lightblue;"></i>
图书管理
</a>
<dl class="layui-nav-child">
<!-- 借阅图书页面 -->
<dd><a href="02borrow.jsp" target="content">借阅图书</a></dd>
<!-- 归还图书页面 -->
<dd><a href="04judge.jsp;" target="content">归还图书</a></dd>
</dl>
</li>
<!-- 报表管理模块 -->
<li class="layui-nav-item">
<a href="javascript:;">
<i class="layui-icon layui-icon-form" style="font-size: 20px; color: orange;"></i>
报表管理
</a>
<dl class="layui-nav-child">
<!-- 借书报表页面 -->
<dd><a href="06borrowTable.jsp" target="content">借书报表</a></dd>
<!-- 还书报表页面 -->
<dd><a href="07returnTable.jsp" target="content">还书报表</a></dd>
</dl>
</li>
<!-- 公告发布模块 -->
<li class="layui-nav-item">
<a href="08announcement.jsp" target="content">
<i class="layui-icon layui-icon-release" style="font-size: 20px; color: yellow;"></i>
发布公告
</a>
</li>
</ul>
</div>
</div>
<!-- 主体内容区域(通过iframe加载子页面) -->
<div class="layui-body">
<iframe src="02borrow.jsp" name="content" height="100%" width="100%" frameborder="0"></iframe>
</div>
<!-- 底部版权信息 -->
<div class="layui-footer">
© 图书管理系统
</div>
// * * 02borrow.jsp
<head> </head>借阅图书
<!-- 主表单容器 -->
<div align="center" style="margin-left: 30%; margin-top: 5%; width: 40%;">
<!-- LayUI表单 -->
<form class="layui-form layui-form-pane" action="03borrowSus.jsp">
<!-- 借阅证号输入 -->
<div class="layui-form-item">
<label class="layui-form-label">借阅证号</label>
<div class="layui-input-inline">
<input type="text" name="userid" lay-verify="required"
placeholder="请输入借阅证号" autocomplete="off" class="layui-input">
</div>
</div>
<!-- 图书编号输入 -->
<div class="layui-form-item">
<label class="layui-form-label">图书编号</label>
<div class="layui-input-inline">
<input type="text" name="bookid" lay-verify="required"
placeholder="请输入图书编号" autocomplete="off" class="layui-input">
</div>
</div>
<!-- 借阅日期选择 -->
<div class="layui-form-item">
<label class="layui-form-label">借阅日期</label>
<div class="layui-input-inline">
<input type="text" name="date1" id="date1" autocomplete="off" class="layui-input">
</div>
</div>
<!-- 提交按钮 -->
<div class="layui-form-item" align="center">
<button class="layui-btn" lay-submit lay-filter="demo2">借阅</button>
</div>
</form>
<!-- LayUI初始化脚本 -->
<script>
layui.use(['form', 'laydate'], function() {
var form = layui.form,
laydate = layui.laydate;
// 初始化日期选择器(借阅日期)
laydate.render({
elem: '#date1', // 绑定输入框ID
type: 'datetime', // 日期时间模式
format: 'yyyy-M-d H:m:s',// 日期格式
value: new Date() // 默认值为当前时间
});
// 监听表单提交
form.on('submit(demo2)', function(data) {
// 实际项目中应移除alert,改为异步提交
layer.alert(JSON.stringify(data.field), { title: '提交数据' });
return false; // 阻止表单自动提交
});
});
</script>
</div>
// * * * 03borrowSus.jsp
<head> </head> <% // 获取表单提交参数 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);
%>
<script>
alert('借阅成功!');
window.location.href = "02borrow.jsp";
</script>
<%
} else {
%>
<script>
alert('借阅未成功!');
window.location.href = "02borrow.jsp";
</script>
<%
}
} catch (Exception e) {
%>
<script>
alert('借阅未成功!');
window.location.href = "02borrow.jsp";
</script>
<%
}
} else {
%>
<script>
alert('该图书已借出!');
window.location.href = "02borrow.jsp";
</script>
<%
}
} else {
%>
<script>
alert('该用户已达到可借阅数量!若需还书,请先归还!');
window.location.href = "02borrow.jsp";
</script>
<%
}
break;
}
}
// 图书馆权限检查失败
if (!validLibrary) {
%>
<script>
alert('该图书未在可借阅的图书馆内!');
window.location.href = "02borrow.jsp";
</script>
<%
}
} else {
%>
<script>
alert('该图书不存在!');
window.location.href = "02borrow.jsp";
</script>
<%
}
} else {
%>
<script>
alert('借阅证已挂失!');
window.location.href = "02borrow.jsp";
</script>
<%
}
} else {
%>
<script>
alert('用户不存在!');
window.location.href = "02borrow.jsp";
</script>
<%
}
} else {
%>
<script>
alert('请先登录!');
window.parent.location.href = "../loginManager.html";
</script>
<%
}
%>
// * * * 04judge.jsp
<head>
</head>
查询图书是否逾期
<!-- 主表单容器 -->
<div align="center" style="margin-left: 30%; margin-top: 5%; width: 40%;">
<!-- LayUI表单 -->
<form class="layui-form layui-form-pane" action="04judgeSus.jsp">
<!-- 图书编号输入 -->
<div class="layui-form-item">
<label class="layui-form-label">图书编号</label>
<div class="layui-input-inline">
<input type="text" name="bookid" lay-verify="required"
placeholder="请输入图书编号" autocomplete="off" class="layui-input">
</div>
</div>
<!-- 查询按钮 -->
<div class="layui-form-item" align="center">
<button class="layui-btn layui-btn-warm" lay-submit lay-filter="demo2">查询</button>
</div>
</form>
<!-- LayUI初始化脚本 -->
<script>
layui.use(['form', 'laydate'], function() {
var form = layui.form,
laydate = layui.laydate;
// 初始化日期选择器(未绑定到表单字段,可能为残留代码)
laydate.render({
elem: '#date1', // 页面中不存在该ID的输入框
type: 'datetime', // 日期时间模式
format: 'yyyy-M-d H:m:s',// 日期格式
min: 0, // 最小时间(当前时间)
max: 0, // 最大时间(当前时间)
value: new Date() // 默认值为当前时间
});
// 监听表单提交
form.on('submit(demo2)', function(data) {
// 实际项目中应使用异步提交(如AJAX)
layer.alert(JSON.stringify(data.field), { title: '提交数据' });
return false; // 阻止表单自动提交
});
});
</script>
</div>
// * * * 04judgeSus.jsp
<head> </head> <% // 获取表单提交的图书编号 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); // 保存逾期费用
// 跳转到图书归还页面
%>
<script>
window.location.href = "04return.jsp";
</script>
<%
} else { // 图书已归还
%>
<script>
alert("该书未借出或不存在!");
window.location.href = "04judge.jsp";
</script>
<%
}
} else { // 未登录处理
%>
<script>
alert('请先登录!');
window.parent.location.href = "../loginManager.html";
</script>
<%
}
%>
// * * * 04return.jsp
<head>
</head>
<!-- 页面标题 -->
<div align="center" style="margin-top: 2%;">
<h1>归还图书</h1>
</div>
<!-- 主表单容器 -->
<div align="center" style="margin-left: 30%; margin-top: 5%; width: 40%;">
<%
// 从会话中获取逾期天数、罚款金额和图书编号
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);
}
%>
<!-- 表单 -->
<form class="layui-form layui-form-pane" action="05returnSus.jsp">
<!-- 逾期信息展示 -->
<div>
<blockquote class="layui-elem-quote layui-quote-nm">
<%= session.getAttribute("mes") %>
<br>
<%= session.getAttribute("mes2") %>
</blockquote>
</div>
<!-- 图书编号输入 -->
<div class="layui-form-item">
<label class="layui-form-label">图书编号</label>
<div class="layui-input-inline">
<input type="text" name="bookid" lay-verify="required"
value="<%= session.getAttribute("book") %>"
autocomplete="off" class="layui-input">
</div>
</div>
<!-- 截止日期显示 -->
<%
// 查询该图书的借阅记录(未归还)
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");
%>
<div class="layui-form-item">
<label class="layui-form-label">截止日期</label>
<div class="layui-input-inline">
<input type="text" name="end" autocomplete="off"
class="layui-input" value="<%= endDate %>">
</div>
</div>
<% } %>
<!-- 归还日期选择 -->
<div class="layui-form-item">
<label class="layui-form-label">归还日期</label>
<div class="layui-input-inline">
<input type="text" name="date1" id="date1" autocomplete="off"
class="layui-input">
</div>
</div>
<!-- 违规信息输入 -->
<div class="layui-form-item">
<label class="layui-form-label">违规信息</label>
<div class="layui-input-inline">
<input type="text" name="ill"
placeholder="若无违规信息,则不填"
autocomplete="off" class="layui-input">
</div>
</div>
<!-- 管理员编号(自动填充,只读) -->
<div class="layui-form-item">
<label class="layui-form-label">管理员编号</label>
<div class="layui-input-inline">
<input type="text" name="managerid" readonly="readonly"
class="layui-input" value="<%= session.getAttribute("manager") %>">
</div>
</div>
<!-- 提交按钮 -->
<div class="layui-form-item" align="center">
<button class="layui-btn layui-btn-warm" lay-submit lay-filter="demo2">
归还
</button>
</div>
</form>
<!-- LayUI初始化脚本 -->
<script>
layui.use(['form', 'laydate'], function() {
var form = layui.form,
laydate = layui.laydate;
// 初始化日期选择器(仅当前时间可选)
laydate.render({
elem: '#date1',
type: 'datetime',
format: 'yyyy-MM-dd H:m:s',
min: 0,
max: 0,
value: new Date()
});
// 监听表单提交
form.on('submit(demo2)', function(data) {
// 实际项目中应使用异步提交(如AJAX)
layer.alert(JSON.stringify(data.field), { title: '提交数据' });
return false; // 阻止表单自动提交
});
});
</script>
</div>
// * * * 05returnSus.jsp
<head>
</head>
<%
// 获取表单提交参数
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});
%>
<script>
alert('归还成功!');
window.location.href = "04judge.jsp";
</script>
<%
} else {
%>
<script>
alert('该图书未借出!');
window.location.href = "04judge.jsp";
</script>
<%
}
}
} catch (SQLException e) {
e.printStackTrace();
%>
<script>
alert('归还未成功!');
window.location.href = "04judge.jsp";
</script>
<%
}
} else {
%>
<script>
alert('请先登录!');
window.parent.location.href = "../loginManager.html";
</script>
<%
}
%>
//* * * 06borrwoTable.jsp
<head>
</head>
<!-- 表格容器(初始隐藏) -->
<table class="layui-hide" id="cardTable" lay-filter="formFilter"></table>
<!-- 头部工具栏模板 -->
<script type="text/html" id="headBar">
条件搜索:
<div class="layui-inline">
<!-- 搜索条件下拉菜单 -->
<select id="condition" name="condition" lay-verify="required">
<option value=""></option>
<option value="card_id">借阅证号</option>
<option value="book_id">图书编号</option>
<option value ="borrow_date">借阅日期</option>
<option value="end_date">截止日期</option>
<option value="return_date">归还日期</option>
<option value="illegal">违章信息</option>
<option value="manager_id">处理人</option>
</select>
</div>
<div class="layui-inline">
<!-- 搜索值输入框 -->
<input class="layui-input" id="conditionValue" name="conditionValue" autocomplete="off">
</div>
<!-- 搜索按钮 -->
<button class="layui-btn" name="condition" data-type="reload" lay-event="search">搜索</button>
</script>
<script>
layui.use(['table', 'jquery'], function() {
var $ = layui.jquery;
var table = layui.table;
// 初始化表格渲染
var tableIns = table.render({
elem: '#cardTable', // 绑定表格容器ID
url: './borrowTable', // 数据接口(Servlet路径)
toolbar: '#headBar', // 绑定头部工具栏模板
cols: [[ // 表格列配置
{field: 'card_id', width: 180, title: '借阅证号', sort: true},
{field: 'book_id', width: 130, title: '图书编号', sort: true},
{field: 'borrow_date', width: 250, title: '借阅日期', sort: true},
{field: 'end_date', title: '截止日期', width: 250, sort: true},
{field: 'return_date', width: 250, title: '归还时间', sort: true},
{field: 'illegal', width: 180, title: '违章信息', sort: true, style: 'color: red;'},
{field: 'manager_id', minWidth: 80, title: '处理人'}
]],
page: true // 启用分页
});
// 头部工具栏事件处理
table.on('toolbar(formFilter)', function(obj) {
var checkStatus = table.checkStatus(obj.config.id);
switch (obj.event) {
case 'search':
// 获取搜索条件和值
var conditionValue = $('#conditionValue');
var condition = $('#condition');
// 重新加载表格数据
tableIns.reload({
where: {
"condition": condition.val(), // 过滤字段
"conditionValue": conditionValue.val() // 过滤值
},
page: {
curr: 1 // 重置为第一页
}
});
break;
case 'add':
// 打开添加借阅证弹窗(未实现)
var addCardLayer = layer.open({
type: 2,
title: '添加借书证',
area: ['800px', '500px'],
maxmin: true,
shadeClose: true,
content: 'cardadd.jsp'
});
break;
}
});
// 侧边工具栏事件处理(未实现)
table.on('tool(formFilter)', function(obj) {
var data = obj.data;
var layEvent = obj.event;
var tr = obj.tr;
switch (obj.event) {
case 'edit':
// 打开编辑弹窗(未实现)
layer.open({
type: 2,
title: '更改信息',
area: ['800px', '600px'],
maxmin: true,
shadeClose: true,
content: ''
});
break;
}
});
});
</script>
//* * * 07returnTable.jsp
<head>
</head>
<!-- 头部工具栏模板 -->
<script type="text/html" id="headBar">
条件搜索:
<div class="layui-inline">
<!-- 搜索条件下拉菜单 -->
<select id="condition" name="condition" lay-verify="required">
<option value=""></option>
<option value="card_id">借阅证号</option>
<option value="book_id">图书编号</option>
<option value="borrow_date">借阅日期</option>
<option value="end_date">截止日期</option>
</select>
</div>
<div class="layui-inline">
<!-- 搜索值输入框 -->
<input class="layui-input" id="conditionValue" name="conditionValue" autocomplete="off">
</div>
<!-- 搜索按钮 -->
<button class="layui-btn" name="condition" data-type="reload" lay-event="search">搜索</button>
</script>
<script>
layui.use(['table', 'jquery'], function() {
var $ = layui.jquery;
var table = layui.table;
// 初始化表格渲染
var tableIns = table.render({
elem: '#cardTable', // 绑定表格容器ID
url: './returnTable', // 数据接口(Servlet路径)
toolbar: '#headBar', // 绑定头部工具栏模板
cols: [[ // 表格列配置
{field: 'card_id', width: 180, title: '借阅证号', sort: true},
{field: 'book_id', width: 130, title: '图书编号', sort: true},
{field: 'borrow_date', width: 250, title: '借阅日期', sort: true},
{field: 'end_date', title: '截止日期', width: 250, sort: true}
]],
page: true // 启用分页
});
// 头部工具栏事件处理
table.on('toolbar(formFilter)', function(obj) {
var checkStatus = table.checkStatus(obj.config.id);
switch (obj.event) {
case 'search':
// 获取搜索条件和值
var conditionValue = $('#conditionValue');
var condition = $('#condition');
// 重新加载表格数据
tableIns.reload({
where: {
"condition": condition.val(), // 过滤字段
"conditionValue": conditionValue.val() // 过滤值
},
page: {
curr: 1 // 重置为第一页
}
});
break;
case 'add':
// 打开添加借阅证弹窗(未实现)
var addCardLayer = layer.open({
type: 2,
title: '添加借书证',
area: ['800px', '500px'],
maxmin: true,
shadeClose: true,
content: 'cardadd.jsp'
});
break;
}
});
// 侧边工具栏事件处理(未实现)
table.on('tool(formFilter)', function(obj) {
var data = obj.data;
var layEvent = obj.event;
var tr = obj.tr;
switch (obj.event) {
case 'edit':
// 打开编辑弹窗(未实现)
layer.open({
type: 2,
title: '更改信息',
area: ['800px', '600px'],
maxmin: true,
shadeClose: true,
content: ''
});
break;
}
});
});
</script>
//* * * 08add.jsp
<head>
</head>
<!-- 公告内容输入 -->
<div class="layui-form-item" style="height:50%;">
<label class="layui-form-label">公告</label>
<div class="layui-input-block">
<textarea name="detail"
lay-verify="required"
placeholder="请输入公告"
autocomplete="off"
class="layui-input"
style="height:300px;"></textarea>
</div>
</div>
<!-- 提交按钮 -->
<div class="layui-form-item">
<div class="layui-input-block">
<button type="submit"
class="layui-btn"
lay-submit=""
lay-filter="submitButton">
<i class="layui-icon layui-icon-release"
style="font-size: 20px; color: yellow;"></i>
发布
</button>
</div>
</div>
</form>
<script>
layui.use(['form', 'jquery'], function() {
var $ = layui.jquery;
var form = layui.form;
var layer = layui.layer;
// 监听表单提交
form.on('submit(submitButton)', function(data) {
// 使用AJAX异步提交表单数据
$.ajax({
url: './announcementAdd', // 后端Servlet路径
method: 'post', // 请求方法
data: data.field, // 表单数据对象
dataType: 'json', // 期望返回JSON格式
success: function(response) {
if (response.code === "0") {
// 提交成功提示
parent.layer.msg("添加成功", {
icon: 6, // 成功图标
time: 500 // 提示持续时间(毫秒)
});
// 500ms后刷新父页面
setTimeout(function() {
parent.location.reload();
}, 500);
} else {
// 失败提示
layer.msg(response.msg);
}
}
});
return false; // 阻止表单默认提交行为
});
});
</script>
//* * *08edit.jsp
<head>
</head>
<%
// 获取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中处理)
}
%>
<!-- 公告编辑表单 -->
<form class="layui-form layui-form-pane" action="" lay-filter="formFilter">
<!-- 隐藏字段:公告ID -->
<input type="text" name="id" value="<%=id %>"
lay-verify="required" required
autocomplete="off"
class="layui-input layui-hide">
<!-- 标题输入 -->
<div class="layui-form-item">
<label class="layui-form-label">标题</label>
<div class="layui-input-block">
<input type="text" name="title"
value="<%=resultSet.getString("title") %>"
lay-verify="required" required
autocomplete="off"
placeholder="请输入标题"
class="layui-input">
</div>
</div>
<!-- 公告内容输入 -->
<div class="layui-form-item">
<label class="layui-form-label">公告</label>
<div class="layui-input-block">
<input type="text" name="detail"
value="<%=resultSet.getString("detail") %>"
lay-verify="required"
placeholder="请输入公告"
autocomplete="off"
class="layui-input">
</div>
</div>
<!-- 提交按钮 -->
<div class="layui-form-item">
<div class="layui-input-block">
<button type="submit" class="layui-btn"
lay-submit lay-filter="submitButton">
立即提交
</button>
</div>
</div>
</form>
<script>
layui.use(['form', 'jquery'], function() {
var $ = layui.jquery;
var form = layui.form;
var layer = layui.layer;
// 监听表单提交
form.on('submit(submitButton)', function(data) {
// 使用AJAX异步提交表单数据
$.ajax({
url: './announcementEdit', // 后端Servlet路径
method: 'post', // 请求方法
data: data.field, // 表单数据对象
dataType: 'json', // 期望返回JSON格式
success: function(response) {
if (response.code === "0") {
// 提交成功提示
parent.layer.msg("修改成功", {
icon: 6, // 成功图标
time: 500 // 提示持续时间(毫秒)
});
// 500ms后刷新父页面
setTimeout(function() {
parent.location.reload();
}, 500);
} else {
// 失败提示
layer.msg(response.msg);
}
},
error: function(xhr, status, error) {
// 网络错误处理
layer.msg('网络请求失败,请检查网络连接');
}
});
return false; // 阻止表单默认提交行为
});
});
</script>
//* * *09managerSelf.jsp
<head>
<!-- 引入Bootstrap框架 -->
<link href="../css/bootstrap.min.css" rel="stylesheet">
<script src="../js/jquery.min.js"></script>
<script src="../js/bootstrap.min.js"></script>
<!-- 引入自定义样式和动画库 -->
<link rel="stylesheet" type="text/css" href="../public/css/default.css" />
<link rel="stylesheet" type="text/css" href="../public/css/component.css" />
<script src="../public/js/modernizr.custom.js"></script>
<!-- 自定义样式 -->
<style>
body {
background-color: white !important;
color: black !important;
}
.md-content {
color: black;
background: white;
position: relative;
border-radius: 3px;
margin: 0 auto;
}
button {
background-color: #009688;
}
button:hover {
background-color: #5FB878;
}
.md-modal {
width: 35%;
}
</style>
</head>
<!-- 管理员基本信息展示 -->
<fieldset class="layui-elem-field" style="width:30%; margin-left:30%; margin-top:5%; height:30%;">
<legend>管理员基本信息</legend>
<div class="layui-field-box" align="center" style="font-size:20px; font-family:YouYuan; margin-top:10%; margin-bottom:10%;">
<%
// 获取当前登录管理员账号
String manacc = session.getAttribute("manager").toString();
// 查询管理员信息(存在SQL注入风险!)
String sql = "select * from manager where ACCOUNT = '" + manacc + "';";
ResultSet rs = gly.executeQuery(sql);
while (rs.next()) {
%>
<!-- 展示基本信息 -->
<p>姓名:<%= rs.getString("name") %></p><br>
<p>账号:<%= rs.getString("account") %></p><br>
<p>邮箱:<%= rs.getString("email") %></p><br>
<!-- 模态框触发按钮 -->
<button class="md-trigger layui-btn layui-btn-radius" data-modal="modal-3">修改名字</button>
<button class="md-trigger layui-btn layui-btn-radius" data-modal="modal-13">修改密码</button>
<button class="md-trigger layui-btn layui-btn-radius" data-modal="modal-1">修改邮箱</button>
<% } %>
</div>
</fieldset>
<!-- 修改密码模态框 -->
<div class="md-modal md-effect-13" id="modal-13">
<div class="md-content">
<h3>修改密码</h3>
<form action="10updateManager.jsp" method="post" class="form-horizontal">
<div class="form-group" align="center" style="margin-left:3%;">
<br>
<label for="psw1" class="col-sm-2 control-label">新密码</label>
<div class="col-sm-10" align="center">
<input type="password" class="form-control" name="psw1" id="password1"
placeholder="请输入新密码" style="width:50%; margin-left:8%;">
</div>
</div>
<br>
<div class="form-group" align="center" style="margin-left:3%;">
<label for="psw2" class="col-sm-2 control-label">确认密码</label>
<div class="col-sm-10">
<input type="password" class="form-control" name="psw2" id="password2"
placeholder="请再次输入密码进行确认" style="width:50%; margin-left:8%;">
</div>
</div>
<div align="center">
<input type="submit" class="layui-btn layui-btn-radius" value="确认">
</div>
<br>
</form>
<button class="md-close layui-btn-radius" style="font-size:14px;">取消</button>
</div>
</div>
<!-- 修改邮箱模态框 -->
<div class="md-modal md-effect-13" id="modal-1">
<div class="md-content">
<h3>修改邮箱</h3>
<form action="10updateManager.jsp" method="post" class="form-horizontal">
<div class="form-group" align="center" style="margin-left:3%;">
<br>
<label for="email1" class="col-sm-2 control-label">新邮箱</label>
<div class="col-sm-10" align="center">
<input type="text" class="form-control" name="email1" id="password1"
placeholder="请输入新邮箱" style="width:50%; margin-left:8%;">
</div>
</div>
<br>
<div class="form-group" align="center" style="margin-left:3%;">
<label for="email2" class="col-sm-2 control-label">确认邮箱</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="email2" id="password2"
placeholder="请再次输入邮箱进行确认" style="width:50%; margin-left:8%;">
</div>
</div>
<div align="center">
<input type="submit" class="layui-btn layui-btn-radius" value="确认">
</div>
<br>
</form>
<button class="md-close layui-btn-radius" style="font-size:14px;">取消</button>
</div>
</div>
<!-- 修改姓名模态框 -->
<div class="md-modal md-effect-13" id="modal-3">
<div class="md-content">
<h3>修改名字</h3>
<form action="10updateManager.jsp" method="post" class="form-horizontal">
<div class="form-group" align="center" style="margin-left:3%;">
<br>
<label for="name1" class="col-sm-2 control-label">新名字</label>
<div class="col-sm-10" align="center">
<input type="text" class="form-control" name="name1" id="password1"
placeholder="请输入新名字" style="width:50%; margin-left:8%;">
</div>
</div>
<br>
<div class="form-group" align="center" style="margin-left:3%;">
<label for="name2" class="col-sm-2 control-label">确认名字</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="name2" id="password2"
placeholder="请再次输入名字进行确认" style="width:50%; margin-left:8%;">
</div>
</div>
<div align="center">
<input type="submit" class="layui-btn layui-btn-radius" value="确认">
</div>
<br>
</form>
<button class="md-close layui-btn-radius" style="font-size:14px;">取消</button>
</div>
</div>
<!-- 模态框遮罩层 -->
<div class="md-overlay"></div>
<!-- 模态框动画脚本 -->
<script src="../public/js/classie.js"></script>
<script src="../public/js/modalEffects.js"></script>
<!-- CSS滤镜兼容脚本 -->
<script>
var polyfilter_scriptpath = '/js/';
</script>
<script src="../public/js/cssParser.js"></script>
<script src="../public/js/css-filters-polyfill.js"></script>
//* * *updateManager.jsp
<head>
</head>
<%
// 获取表单提交的参数
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) {
%>
<script>
alert('密码修改成功!');
window.location.href = "09managerSelf.jsp";
</script>
<%
} else {
%>
<script>
alert('密码修改失败!');
window.location.href = "09managerSelf.jsp";
</script>
<%
}
} catch (SQLException e) {
e.printStackTrace();
%>
<script>
alert('数据库操作失败!');
window.location.href = "09managerSelf.jsp";
</script>
<%
}
} else {
%>
<script>
alert('密码不一致或为空!');
window.location.href = "09managerSelf.jsp";
</script>
<%
}
}
// 邮箱修改逻辑
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) {
%>
<script>
alert('邮箱修改成功!');
window.location.href = "09managerSelf.jsp";
</script>
<%
} else {
%>
<script>
alert('邮箱修改失败!');
window.location.href = "09managerSelf.jsp";
</script>
<%
}
} catch (SQLException e) {
e.printStackTrace();
%>
<script>
alert('数据库操作失败!');
window.location.href = "09managerSelf.jsp";
</script>
<%
}
} else {
%>
<script>
alert('邮箱不一致或为空!');
window.location.href = "09managerSelf.jsp";
</script>
<%
}
}
// 姓名修改逻辑
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) {
%>
<script>
alert('姓名修改成功!');
window.location.href = "09managerSelf.jsp";
</script>
<%
} else {
%>
<script>
alert('姓名修改失败!');
window.location.href = "09managerSelf.jsp";
</script>
<%
}
} catch (SQLException e) {
e.printStackTrace();
%>
<script>
alert('数据库操作失败!');
window.location.href = "09managerSelf.jsp";
</script>
<%
}
} else {
%>
<script>
alert('姓名不一致或为空!');
window.location.href = "09managerSelf.jsp";
</script>
<%
}
} else {
%>
<script>
alert('请选择要修改的内容!');
window.location.href = "09managerSelf.jsp";
</script>
<%
}
%>
// * * * loginManager.html
<head>
<!-- 引入jQuery库 -->
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<!-- Bootstrap框架样式 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
<!-- Bootstrap核心脚本 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
<!-- 可选的Bootstrap主题 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css">
<!-- 自定义样式 -->
<link rel="stylesheet" href="./public/css/animate.css">
<link rel="stylesheet" href="./public/css/login.css">
</head>
工作人员登录
<!-- 底部快捷链接 -->
<div style="position:fixed; bottom:0; right:0;">
<!-- 读者系统入口 -->
<a href="reader/04readerFrame.jsp" target="_blank">
<img src="public/image/reader.png" width="50px" height="50px">
</a>
<br>
<!-- 系统管理员入口 -->
<a href="adminLogin.html" target="_blank">
<img src="public/image/admin.png" width="50px" height="50px">
</a>
</div>
<!-- 弹出层插件 -->
<script src="./public/js/layer/layer.js"></script>
<script>
$(function() {
// 登录按钮点击事件
$("input[type=submit]").click(function() {
// 使用AJAX提交表单
$.ajax({
url: "./managerLogin", // 后端Servlet路径
type: "post", // 请求方法
data: $("form").serialize(), // 序列化表单数据
dataType: "json", // 期望返回JSON格式
success: function(data) {
if (data.code === 0) {
// 登录成功提示
layer.msg("登录成功", {
icon: 6, // 成功图标
time: 1000 // 提示持续时间(毫秒)
}, function() {
// 跳转至目标页面
location.href = data.url;
});
} else {
// 登录失败提示
layer.open({
title: "登录失败",
content: data.msg,
icon: 5, // 错误图标
anim: 6 // 动画效果
});
}
}
});
return false; // 阻止表单默认提交行为
});
});
</script>
// * * * src/main/webapp/index.jsp
<head>
</head>
<%
// 使用response.sendRedirect方法将页面重定向到指定的URL
// 这里将页面重定向到名为04readerFrame.jsp的页面,该页面位于reader目录下
response.sendRedirect("./reader/04readerFrame.jsp");
%>