From 19242725b7189b7a8883915299d1c3a926ca1e5b Mon Sep 17 00:00:00 2001 From: lotus Date: Mon, 9 Dec 2024 22:17:48 +0800 Subject: [PATCH] =?UTF-8?q?java=E7=AC=AC05=E6=AC=A1=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java/com/dao/BookDao.java | 88 ++++++++++++++++++ java/com/demo/BookBean.java | 64 +++++++++++++ java/com/demo/BookInsertServlet.java | 64 +++++++++++++ java/com/demo/BookQueryServlet.java | 62 ++++++++++++ java/com/demo/BookQueryServlet2.java | 71 ++++++++++++++ java/com/demo/BookQueryServlet3.java | 52 +++++++++++ webapp/META-INF/context.xml | 13 +++ .../WEB-INF/lib/mysql-connector-j-8.0.32.jar | Bin 0 -> 2480823 bytes webapp/application.jsp | 21 +++++ webapp/bookInsert.jsp | 21 +++++ webapp/bookQuery.jsp | 13 +++ webapp/displayBook.jsp | 23 +++++ webapp/error.jsp | 4 + webapp/expection.jsp | 23 +++++ webapp/insertBook.jsp | 27 ++++++ webapp/out.jsp | 14 +++ webapp/request.jsp | 13 +++ webapp/session.jsp | 12 +++ webapp/syntax_error.jsp | 9 ++ 19 files changed, 594 insertions(+) create mode 100644 java/com/dao/BookDao.java create mode 100644 java/com/demo/BookBean.java create mode 100644 java/com/demo/BookInsertServlet.java create mode 100644 java/com/demo/BookQueryServlet.java create mode 100644 java/com/demo/BookQueryServlet2.java create mode 100644 java/com/demo/BookQueryServlet3.java create mode 100644 webapp/META-INF/context.xml create mode 100644 webapp/WEB-INF/lib/mysql-connector-j-8.0.32.jar create mode 100644 webapp/application.jsp create mode 100644 webapp/bookInsert.jsp create mode 100644 webapp/bookQuery.jsp create mode 100644 webapp/displayBook.jsp create mode 100644 webapp/error.jsp create mode 100644 webapp/expection.jsp create mode 100644 webapp/insertBook.jsp create mode 100644 webapp/out.jsp create mode 100644 webapp/request.jsp create mode 100644 webapp/session.jsp create mode 100644 webapp/syntax_error.jsp diff --git a/java/com/dao/BookDao.java b/java/com/dao/BookDao.java new file mode 100644 index 0000000..499f3e6 --- /dev/null +++ b/java/com/dao/BookDao.java @@ -0,0 +1,88 @@ +package com.dao; + +import java.sql.*; +import javax.sql.*; +import javax.naming.*; +import com.demo.BookBean; + +public class BookDao { + private static InitialContext context = null; + private DataSource dataSource = null; + + public BookDao() { + try { + if (context == null) { + context = new InitialContext(); + } + dataSource = (DataSource)context.lookup("java:comp/env/jdbc/demo"); + } catch (NamingException e) { + e.printStackTrace(); + } + } + + // 根据书号查询图书信息 + public BookBean searchBook(String bookid) { + Connection dbconn = null; + PreparedStatement pstmt = null; + ResultSet rst = null; + BookBean book = new BookBean(); + + try { + dbconn = dataSource.getConnection(); + pstmt = dbconn.prepareStatement("SELECT * FROM books WHERE bookid=?"); + pstmt.setString(1, bookid); + rst = pstmt.executeQuery(); + + if (rst.next()) { + book.setBookid(rst.getString("bookid")); + book.setTitle(rst.getString("title")); + book.setAuthor(rst.getString("author")); + book.setPublisher(rst.getString("publisher")); + book.setPrice(rst.getDouble("price")); + return book; + } else { + return null; + } + } catch (SQLException se) { + se.printStackTrace(); + return null; + } finally { + try { + if (rst != null) rst.close(); + if (pstmt != null) pstmt.close(); + if (dbconn != null) dbconn.close(); + } catch (SQLException se) { + se.printStackTrace(); + } + } + } + + // 插入一本图书记录 + public boolean insertBook(BookBean book) { + Connection dbconn = null; + PreparedStatement pstmt = null; + + try { + dbconn = dataSource.getConnection(); + pstmt = dbconn.prepareStatement("INSERT INTO books VALUES(?,?,?,?,?)"); + pstmt.setString(1, book.getBookid()); + pstmt.setString(2, book.getTitle()); + pstmt.setString(3, book.getAuthor()); + pstmt.setString(4, book.getPublisher()); + pstmt.setDouble(5, book.getPrice()); + + int result = pstmt.executeUpdate(); + return result > 0; + } catch (SQLException se) { + se.printStackTrace(); + return false; + } finally { + try { + if (pstmt != null) pstmt.close(); + if (dbconn != null) dbconn.close(); + } catch (SQLException se) { + se.printStackTrace(); + } + } + } +} diff --git a/java/com/demo/BookBean.java b/java/com/demo/BookBean.java new file mode 100644 index 0000000..e939f10 --- /dev/null +++ b/java/com/demo/BookBean.java @@ -0,0 +1,64 @@ +package com.demo; + +public class BookBean { + // 定义私有属性 + private String bookid; + private String title; + private String author; + private String publisher; + private double price; + + // 无参数构造方法 + public BookBean() { + } + + // 带参数构造方法 + public BookBean(String bookid, String title, String author, String publisher, double price) { + this.bookid = bookid; + this.title = title; + this.author = author; + this.publisher = publisher; + this.price = price; + } + + // Getter和Setter方法 + public String getBookid() { + return bookid; + } + + public void setBookid(String bookid) { + this.bookid = bookid; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getPublisher() { + return publisher; + } + + public void setPublisher(String publisher) { + this.publisher = publisher; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } +} \ No newline at end of file diff --git a/java/com/demo/BookInsertServlet.java b/java/com/demo/BookInsertServlet.java new file mode 100644 index 0000000..de22fe8 --- /dev/null +++ b/java/com/demo/BookInsertServlet.java @@ -0,0 +1,64 @@ +package com.demo; + +import java.io.*; +import javax.servlet.*; +import javax.servlet.http.*; +import com.demo.BookBean; +import com.dao.BookDao; +import javax.servlet.annotation.WebServlet; + +@WebServlet("/BookInsertServlet") +public class BookInsertServlet extends HttpServlet { + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + // 设置请求和响应的字符编码 + request.setCharacterEncoding("UTF-8"); + response.setCharacterEncoding("UTF-8"); + response.setContentType("text/html;charset=UTF-8"); + + String message = null; + try { + // 获取并验证请求参数 + String bookid = request.getParameter("bookid"); + String title = request.getParameter("title"); + String author = request.getParameter("author"); + String publisher = request.getParameter("publisher"); + String priceStr = request.getParameter("price"); + + // 参数验证 + if (bookid == null || title == null || author == null || + publisher == null || priceStr == null || + bookid.trim().isEmpty() || title.trim().isEmpty() || + author.trim().isEmpty() || publisher.trim().isEmpty() || + priceStr.trim().isEmpty()) { + message = "请填写完整的图书信息!"; + request.setAttribute("result", message); + request.getRequestDispatcher("/bookInsert.jsp").forward(request, response); + return; + } + + float price = Float.parseFloat(priceStr); + + // 创建图书对象 + BookBean book = new BookBean(bookid, title, author, publisher, price); + BookDao bookdao = new BookDao(); + boolean success = bookdao.insertBook(book); + + message = success ? "成功插入一条记录!" : "插入记录错误!"; + + } catch (NumberFormatException e) { + message = "价格格式不正确!"; + } catch (Exception e) { + message = "系统错误:" + e.getMessage(); + e.printStackTrace(); + } + + request.setAttribute("result", message); + request.getRequestDispatcher("/bookInsert.jsp").forward(request, response); + } + + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doPost(request, response); + } +} diff --git a/java/com/demo/BookQueryServlet.java b/java/com/demo/BookQueryServlet.java new file mode 100644 index 0000000..b65c2c1 --- /dev/null +++ b/java/com/demo/BookQueryServlet.java @@ -0,0 +1,62 @@ +package com.demo; + +import java.io.IOException; +import javax.servlet.*; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.*; +import java.sql.*; + +@WebServlet("/BookQueryServlet") +public class BookQueryServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + // 数据库连接信息常量 +// private static final String DB_URL = "jdbc:mysql://47.242.181.61:33060/demo?useSSL=false&serverTimezone=UTC"; + private static final String DB_URL = "jdbc:mysql://47.242.181.61:33060/demo?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true"; + private static final String DB_USER = "root"; + private static final String DB_PASSWORD = "lotus"; + + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + String bookid = request.getParameter("bookid"); + if (bookid == null || bookid.trim().isEmpty()) { + request.setAttribute("error", "图书ID不能为空"); + request.getRequestDispatcher("/error.jsp").forward(request, response); + return; + } + + try (Connection conn = getConnection(); + PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM books WHERE bookid = ?"); + ) { + pstmt.setString(1, bookid); + + try (ResultSet rst = pstmt.executeQuery()) { + if (rst.next()) { + BookBean book = new BookBean(); + book.setBookid(rst.getString("bookid")); + book.setTitle(rst.getString("title")); + book.setAuthor(rst.getString("author")); + book.setPrice(rst.getFloat("price")); + book.setPublisher(rst.getString("publisher")); + + request.setAttribute("book", book); + request.getRequestDispatcher("/displayBook.jsp").forward(request, response); + } else { + request.setAttribute("error", "未找到ID为 " + bookid + " 的图书"); + request.getRequestDispatcher("/error.jsp").forward(request, response); + } + } + } catch (Exception e) { + String errorMsg = "数据库操作失败: " + e.getMessage(); + log(errorMsg, e); + request.setAttribute("error", errorMsg); + request.getRequestDispatcher("/error.jsp").forward(request, response); + } + } + + private Connection getConnection() throws SQLException, ClassNotFoundException { + Class.forName("com.mysql.cj.jdbc.Driver"); + return DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD); + } +} diff --git a/java/com/demo/BookQueryServlet2.java b/java/com/demo/BookQueryServlet2.java new file mode 100644 index 0000000..b26bd8d --- /dev/null +++ b/java/com/demo/BookQueryServlet2.java @@ -0,0 +1,71 @@ +package com.demo; + +import java.io.*; +import java.sql.*; +import javax.servlet.*; +import javax.servlet.http.*; +import com.demo.BookBean; +import javax.sql.DataSource; +import javax.naming.*; +import javax.servlet.annotation.WebServlet; + +@WebServlet("/BookQueryServlet2") +public class BookQueryServlet2 extends HttpServlet { + /** + * + */ + private static final long serialVersionUID = 1L; + Connection dbconn; + + public void init() { + try { + Context context = new InitialContext(); + DataSource ds = (DataSource)context.lookup("java:comp/env/jdbc/demo"); + dbconn = ds.getConnection(); + } catch(NamingException ne) { + log("数据源查找失败: " + ne); + } catch(SQLException se) { + log("数据库连接失败: " + se); + } + } + + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + String bookid = request.getParameter("bookid"); + try { + String sql = "SELECT * FROM books WHERE bookid = ?"; + PreparedStatement pstmt = dbconn.prepareStatement(sql); + pstmt.setString(1, bookid); + ResultSet rst = pstmt.executeQuery(); + + if (rst.next()) { + BookBean book = new BookBean(); + book.setBookid(rst.getString("bookid")); + book.setTitle(rst.getString("title")); + book.setAuthor(rst.getString("author")); + book.setPrice(rst.getDouble("price")); + book.setPublisher(rst.getString("publisher")); + request.getSession().setAttribute("book", book); + response.sendRedirect("/helloweb/displayBook.jsp"); + } else { + response.sendRedirect("/helloweb/error.jsp"); + } + + rst.close(); + pstmt.close(); + } catch(SQLException e) { + e.printStackTrace(); + response.sendRedirect("/helloweb/error.jsp"); + } + } + + public void destroy() { + try { + if (dbconn != null && !dbconn.isClosed()) { + dbconn.close(); + } + } catch(Exception e) { + e.printStackTrace(); + } + } +} diff --git a/java/com/demo/BookQueryServlet3.java b/java/com/demo/BookQueryServlet3.java new file mode 100644 index 0000000..5e03334 --- /dev/null +++ b/java/com/demo/BookQueryServlet3.java @@ -0,0 +1,52 @@ +package com.demo; + +import java.io.*; +import javax.servlet.*; +import javax.servlet.http.*; +import com.demo.BookBean; +import com.dao.BookDao; +import javax.servlet.annotation.WebServlet; + +@WebServlet("/BookQueryServlet3") +public class BookQueryServlet3 extends HttpServlet { + + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + // 设置请求和响应的字符编码 + request.setCharacterEncoding("UTF-8"); + response.setCharacterEncoding("UTF-8"); + + // 获取请求参数 + String bookid = request.getParameter("bookid"); + + // 参数验证 + if (bookid == null || bookid.trim().isEmpty()) { + response.sendRedirect("/helloweb/errorPage.jsp"); + return; + } + + try { + // 查询图书信息 + BookDao bookdao = new BookDao(); + BookBean book = bookdao.searchBook(bookid); + + if (book != null) { + // 将图书信息存储在会话中 + request.getSession().setAttribute("book", book); + response.sendRedirect("/helloweb/displayBook.jsp"); + } else { + response.sendRedirect("/helloweb/errorPage.jsp"); + } + } catch (Exception e) { + // 记录异常信息 + e.printStackTrace(); + response.sendRedirect("/helloweb/errorPage.jsp"); + } + } + + // 处理GET请求 + public void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doPost(request, response); + } +} diff --git a/webapp/META-INF/context.xml b/webapp/META-INF/context.xml new file mode 100644 index 0000000..5e0165b --- /dev/null +++ b/webapp/META-INF/context.xml @@ -0,0 +1,13 @@ + + + + diff --git a/webapp/WEB-INF/lib/mysql-connector-j-8.0.32.jar b/webapp/WEB-INF/lib/mysql-connector-j-8.0.32.jar new file mode 100644 index 0000000000000000000000000000000000000000..184327c180ed53fef153568ca1a9994324a07eea GIT binary patch literal 2480823 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