十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

JavaEE图书管理系统:原生Servlet+JSP实战指南

JavaEE图书管理系统:原生Servlet+JSP实战指南 简介本资源是一个基于JavaEE企业级技术栈开发的完整图书管理系统项目面向Java初学者与进阶开发者用于深入理解MVC架构、Web层交互、数据库操作及企业级框架集成。项目采用Servlet/JSPJDBC或Spring MVCMyBatis等主流组合实现涵盖用户管理、图书增删改查、借阅记录等核心功能并集成Bootstrap前端界面与Spring Security基础权限控制。压缩包共93个文件含21个Java源码、11个JSP页面、10个XML配置如struts.xml、web.xml、21个JAR依赖库及CSS/JS/图片等资源整体6.62MB结构清晰适配Eclipse或IntelliJ IDEA直接导入运行。已有144人学习下载提供可运行的完整工程骨架、分层代码组织范例及典型企业级技术落地实践是掌握JavaEE全栈开发流程的优质入门与复现型学习材料。1. 这不是“又一个Java Web练手项目”它是一套可部署、可调试、可扩展的JavaEE图书管理骨架你下载的基于javaee的图书管理系统.zip表面看是毕业设计常见题但实际藏着一套被低估的JavaEE工程实践范式——它不依赖Spring Boot自动装配不靠Maven一键拉取全部依赖而是用原生ServletJSPJDBCJSTL构建出清晰分层、可定位、可替换的技术栈。这意味着你能一眼看清请求如何从HTTP进Filter、经Servlet调度、查DataSource、渲染JSP也能在Tomcat日志里精准捕获SQL执行耗时、会话超时原因、JNDI绑定失败点。它适合两类人刚学完《Java Web编程技术》想验证知识闭环的学生以及需要快速搭建内部文档/资产目录系统、又不想引入复杂框架的运维或DBA。别被.zip后缀迷惑——解压后看到的不是静态HTML而是web.xml声明式配置、WEB-INF/lib下明确版本的javax.servlet-api-3.1.0.jar、mysql-connector-java-5.1.47.jar以及按MVC拆分的src/com/book/dao/BookDAO.java和WebContent/jsp/list.jsp。这才是JavaEE本该有的样子可控、透明、无黑盒。2. 搭建JavaEE运行环境从JDK到Tomcat再到VS Code的最小可行链路2.1 JDK与Tomcat版本对齐为什么必须用JDK 8 Tomcat 8.5JavaEE规范版本与JDK/Tomcat强绑定。基于javaee的图书管理系统.zip中web.xml头声明为web-app version3.1这对应JavaEE 7规范要求容器支持Servlet 3.1。而Servlet 3.1的官方兼容列表明确要求JDK最低版本为1.7但Tomcat 8.0才完整实现3.1特性如异步Servlet、注解式Filter。实测发现若用JDK 11Tomcat 9WebServlet(/book)注解可能被忽略导致404若用JDK 17Tomcat 10则javax.servlet.*包名已升级为jakarta.servlet.*整个项目编译直接失败。因此必须锁定JDK 8u202 Tomcat 8.5.90组合。验证方法解压Tomcat后进入bin目录执行version.batWindows或./version.shLinux输出应含Server version: Apache Tomcat/8.5.90和JVM Version: 1.8.0_202-b08。提示不要用java -version单独验证JDK——需确保Tomcat启动脚本中JAVA_HOME指向JDK 8安装路径而非系统默认JDK。Windows下检查tomcat/bin/setenv.batLinux下检查tomcat/bin/setenv.sh确认set JAVA_HOMEC:\Program Files\Java\jdk1.8.0_202路径需真实存在。2.2 VS Code配置JavaEE开发环境三步完成语言服务、编译与热部署VS Code本身不内置JavaEE支持需通过插件链构建完整工作流。核心是三个插件协同Extension Pack for Java提供基础语法校验、Tomcat for Visual Studio Code管理服务器生命周期、Language Support for Java(TM) by Red Hat解析web.xml和JSP标签库。配置步骤如下2.2.1 配置Java Runtime与Project SDK在VS Code中打开解压后的项目根目录含src、WebContent、build.xml的文件夹按CtrlShiftP调出命令面板输入Java: Configure Java Runtime选择JDK 8作为默认JRE。接着右键点击src文件夹 →Java: Configure Classpath→ 在弹出窗口中点击Add Library→ 选择Tomcat 8.5安装目录下的lib文件夹路径如C:\apache-tomcat-8.5.90\lib勾选catalina.jar、servlet-api.jar、jsp-api.jar、el-api.jar——这四者是JavaEE Web容器核心API缺一不可。2.2.2 配置Tomcat服务器并关联项目安装Tomcat for Visual Studio Code插件后侧边栏出现Tomcat图标。点击 Add Server→ 选择Apache Tomcat→ 浏览到C:\apache-tomcat-8.5.90目录 → 点击Finish。随后右键新添加的服务器 →Add Deployment→ 选择当前项目 → 设置Context Path为/book与web.xml中context-param一致→Deploy。此时VS Code会在.vscode/settings.json中自动生成{ tomcat.servers: [ { name: Tomcat 8.5, path: C:\\apache-tomcat-8.5.90, deployments: [ { project: ./, contextPath: /book } ] } ] }2.2.3 启动与热部署验证点击Tomcat侧边栏的绿色三角形启动按钮。观察VS Code底部状态栏当显示Tomcat 8.5: Running且终端输出INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [X] milliseconds时说明服务就绪。此时访问http://localhost:8080/book应看到登录页面。修改任意JSP文件如WebContent/jsp/login.jsp保存后VS Code会自动触发Reload无需重启Tomcat——这是Tomcat for VS Code插件监听文件变更并调用Manager App的/reload接口实现的。3. 解析项目结构与核心流程从web.xml入口到DAO层数据落地3.1 web.xml驱动的请求路由为什么Filter优先于Servletweb.xml是JavaEE项目的中枢神经。在本系统中其关键配置有三处!-- 定义全局上下文参数 -- context-param param-namecontextConfigLocation/param-name param-value/WEB-INF/web.xml/param-value /context-param !-- 配置字符编码过滤器 -- filter filter-nameCharacterEncodingFilter/filter-name filter-classcom.book.filter.CharacterEncodingFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param /filter filter-mapping filter-nameCharacterEncodingFilter/filter-name url-pattern/*/url-pattern /filter-mapping !-- 配置前端控制器Servlet -- servlet servlet-nameBookServlet/servlet-name servlet-classcom.book.servlet.BookServlet/servlet-class /servlet servlet-mapping servlet-nameBookServlet/servlet-name url-pattern/book/*/url-pattern /servlet-mapping注意CharacterEncodingFilter的url-pattern/*/url-pattern确保所有请求包括静态资源都先经过此Filter解决中文乱码问题而BookServlet的url-pattern/book/*/url-pattern则将/book/add、/book/list等路径交由其处理。执行顺序严格为Filter chain → Servlet service() → JSP render。若跳过Filter直接访问Servlet数据库插入中文会变成??这是初学者最常踩的坑。3.2 BookServlet的MVC调度逻辑URL路径如何映射到具体操作BookServlet采用传统if-else分支而非注解代码更易追踪// com/book/servlet/BookServlet.java protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String path request.getRequestURI(); // 如 /book/list String action path.substring(path.lastIndexOf(/) 1); // 提取 list if (list.equals(action)) { ListBook books bookDAO.findAll(); request.setAttribute(bookList, books); request.getRequestDispatcher(/jsp/list.jsp).forward(request, response); } else if (add.equals(action)) { // 处理新增逻辑... } else if (delete.equals(action)) { // 处理删除逻辑... } }关键点在于request.getRequestDispatcher(/jsp/list.jsp).forward(request, response)——这是服务器端跳转浏览器URL不变仍为/book/list且request对象中的属性如bookList能传递到JSP。若误用response.sendRedirect(/jsp/list.jsp)则变为客户端重定向request属性丢失JSP中c:forEach items${bookList} varbook将报空指针异常。3.3 JDBC连接池配置为什么用DBCP而不是直接new Connection项目使用Apache Commons DBCP 1.4管理数据库连接在src/jdbc.properties中定义driverClassNamecom.mysql.jdbc.Driver urljdbc:mysql://localhost:3306/bookdb?useUnicodetruecharacterEncodingUTF-8 usernameroot password123456 initialSize5 maxActive20 maxWait60000BookDAO通过BasicDataSource获取连接public class BookDAO { private static BasicDataSource dataSource; static { Properties props new Properties(); props.load(BookDAO.class.getClassLoader().getResourceAsStream(jdbc.properties)); dataSource new BasicDataSource(); dataSource.setDriverClassName(props.getProperty(driverClassName)); dataSource.setUrl(props.getProperty(url)); dataSource.setUsername(props.getProperty(username)); dataSource.setPassword(props.getProperty(password)); dataSource.setInitialSize(Integer.parseInt(props.getProperty(initialSize))); dataSource.setMaxActive(Integer.parseInt(props.getProperty(maxActive))); } public ListBook findAll() throws SQLException { Connection conn dataSource.getConnection(); // 从此处获取连接 // ... 执行查询 conn.close(); // 归还连接到池非真正关闭 return books; } }注意conn.close()调用的是DBCP的代理Connection的close()方法实际将连接放回池中若直接new DriverManager.getConnection()每次查询都新建物理连接100并发时MySQL会报Too many connections错误。4. 数据库与业务逻辑落地MySQL建库、表结构及DAO层关键实现4.1 创建bookdb数据库与book表字符集与引擎必须匹配执行以下SQL创建数据库及表注意utf8mb4字符集CREATE DATABASE bookdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE bookdb; CREATE TABLE book ( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(100) NOT NULL, author VARCHAR(50) NOT NULL, isbn VARCHAR(20), price DECIMAL(10,2) NOT NULL, publish_date DATE, status ENUM(available, borrowed, lost) DEFAULT available, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;关键点CHARACTER SET utf8mb4支持emoji和四字节UTF-8字符ENGINEInnoDB支持事务和外键虽本系统未用外键但为后续扩展预留status字段用ENUM类型避免前端传入非法值如deleted数据库层即拦截。4.2 BookDAO的CRUD实现PreparedStatement防注入与结果集映射BookDAO中addBook()方法体现JavaEE安全最佳实践public void addBook(Book book) throws SQLException { String sql INSERT INTO book (title, author, isbn, price, publish_date, status) VALUES (?, ?, ?, ?, ?, ?); Connection conn dataSource.getConnection(); PreparedStatement pstmt conn.prepareStatement(sql); pstmt.setString(1, book.getTitle()); // 参数化赋值杜绝SQL注入 pstmt.setString(2, book.getAuthor()); pstmt.setString(3, book.getIsbn()); pstmt.setBigDecimal(4, book.getPrice()); pstmt.setDate(5, new java.sql.Date(book.getPublishDate().getTime())); pstmt.setString(6, book.getStatus()); pstmt.executeUpdate(); // 执行插入 pstmt.close(); conn.close(); }对比危险写法INSERT INTO book VALUES ( book.getTitle() , ...)——若title含 OR 11将导致全表删除。而PreparedStatement预编译SQL参数仅作为数据传输不参与SQL语法解析。4.3 JSP页面的数据绑定JSTL与EL表达式如何协作渲染列表WebContent/jsp/list.jsp使用标准标签库展示数据% taglib prefixc urihttp://java.sun.com/jsp/jstl/core % % page contentTypetext/html;charsetUTF-8 languagejava % html headtitle图书列表/title/head body h2图书管理/h2 table border1 tr thID/thth书名/thth作者/thth价格/thth操作/th /tr c:forEach items${bookList} varbook tr td${book.id}/td td${book.title}/td td${book.author}/td td${book.price}/td td a href/book/delete?id${book.id}删除/a a href/book/edit?id${book.id}编辑/a /td /tr /c:forEach /table /body /htmlc:forEach遍历request中bookList属性List varbook生成每个Book对象的EL变量${book.title}通过JavaBean规范调用getTitle()方法。若页面空白首要检查bookList是否为空——在BookServlet中加System.out.println(Size: books.size());验证DAO查询结果。5. 调试与排错实战定位404、500、乱码三大高频故障5.1 404错误排查从URL路径到web.xml映射的逐层验证当访问http://localhost:8080/book/list返回404按此顺序检查确认Tomcat是否启动成功查看logs/catalina.out末尾是否有INFO ... Server startup字样确认应用是否部署成功访问http://localhost:8080/manager/html需在conf/tomcat-users.xml中配置manager角色在应用列表中查找/book状态应为running确认web.xml中servlet-mapping路径url-pattern/book/*/url-pattern意味着/book/list匹配但/booklist不匹配确认BookServlet类路径com.book.servlet.BookServlet必须存在于WEB-INF/classes/com/book/servlet/BookServlet.class若VS Code编译后class文件在out/production/...目录需在VS Code设置中启用java.configuration.updateBuildConfiguration: interactive确保编译输出到WEB-INF/classes。5.2 500错误定位从堆栈日志到具体行号的精准打击500错误必看logs/catalina.out。典型场景如数据库连接失败Caused by: java.sql.SQLException: Access denied for user rootlocalhost (using password: YES)此时检查jdbc.properties中username和password是否与MySQL实际账户一致若报java.lang.ClassNotFoundException: com.mysql.jdbc.Driver说明mysql-connector-java-5.1.47.jar未放入WEB-INF/lib——JavaEE项目中JDBC驱动必须放在WEB-INF/lib不能只配在VS Code的Classpath里。5.3 中文乱码终极解决方案三处UTF-8强制统一乱码问题必查三处位置配置项正确值验证方式MySQL客户端my.cnf中[client]段default-character-setutf8mb4mysql -u root -p -e SHOW VARIABLES LIKE character%;Tomcat连接池jdbc.properties中url参数?useUnicodetruecharacterEncodingUTF-8查看BookDAO中dataSource.getUrl()输出JSP页面% page contentTypetext/html;charsetUTF-8 %必须存在且值为UTF-8查看浏览器开发者工具Network选项卡Response Headers中Content-Type是否含charsetUTF-8若仍乱码在CharacterEncodingFilter的doFilter()方法中加System.out.println(Request encoding: request.getCharacterEncoding())确认Filter确实生效。5.4 表单提交中文变问号POST与GET的编码差异处理GET请求如/book/delete?id1的中文参数需在Tomcatconf/server.xml中Connector标签加URIEncodingUTF-8Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 URIEncodingUTF-8 /POST请求如新增图书表单由CharacterEncodingFilter处理但需确保HTML表单form未设置accept-charset属性否则会覆盖Filter设置。验证方法在BookServlet中打印request.getParameter(title)若为??说明编码链断裂。提示在BookServlet的doPost()开头加request.setCharacterEncoding(UTF-8)是冗余操作——CharacterEncodingFilter已提前执行此处再设无效反而暴露对Filter机制理解偏差。本文还有配套的精品资源点击获取
返回列表