Java Web 教学项目 - 超级简单的学生管理系统
项目地址:Java Web Demo 可直接拉下来学习!
📚 项目简介
项目地址:Java Web Demo 可直接拉下来学习!
本项目是一个用于教学演示的 Java Web 学生管理系统 ,目的是帮助初学者理解传统的 Java Web 项目是如何构建和运行的,整体页面功能较少。

🎯 项目目标
- 展示 Java Web 项目的标准结构和开发流程
- 演示前后端分离的开发模式(逻辑上是前后端分析的,因为不是用模版引擎渲染页面,但前端和后端代码是放在一个项目中的,方便开发部署)
- 展示 Java Web 的后端开发内容:
- 演示传统的 Servlet 技术如何处理 HTTP 请求
- 演示 web.xml 配置后端的 Servlet 和 Filter 等组件
- 帮助理解 Web 服务器如何运行 Java Web 应用,以及如何打包 War 包部署
- 展示 Java Web 的前端开发内容:
- 演示 Java Web 项目中如何使用 Vue 和 Element UI 实现前端页面的交互
🛠️ 技术栈
| 分类 | 技术 | 说明 |
|---|---|---|
| 后端 | JDK 1.8 | Java 开发工具包 |
| Maven | 项目构建和依赖管理工具 | |
| Servlet 3.1 | Java Web 核心 API | |
| Jetty 9.4 | 轻量级 Web 服务器 | |
| 前端 | Vue 2.x | 渐进式 JavaScript 框架 |
| Element UI 2.x | Vue 组件库 | |
| Axios | HTTP 请求库 |
📁 项目结构详解
Java Web 标准项目结构(未采用模版引擎渲染页面)
一个标准的 Java Web 项目(未采用模版引擎渲染页面)通常采用以下目录结构:
java-web-demo/
├── pom.xml # Maven 项目配置文件(核心)
├── src/
│ ├── main/
│ │ ├── java/ # Java 源代码目录
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── student/
│ │ │ ├── dao/ # 数据访问层(操作数据)
│ │ │ ├── dto/ # 数据传输对象(封装响应数据)
│ │ │ ├── filter/ # 过滤器(拦截请求)
│ │ │ ├── model/ # 数据模型(实体类)
│ │ │ ├── servlet/ # Servlet(处理请求)
│ │ │ └── util/ # 工具类
│ │ ├── resources/ # 资源文件目录
│ │ │ └── public/ # 前端静态资源
│ │ │ ├── css/ # CSS 样式文件
│ │ │ ├── js/ # JavaScript 文件
│ │ │ ├── error/ # 错误页面
│ │ │ ├── index.html # 主页
│ │ │ ├── student-query.html
│ │ │ └── student-save.html
│ │ └── webapp/ # Web 应用目录
│ │ └── WEB-INF/
│ │ └── web.xml # Web 配置文件(核心)
│ └── test/ # 测试代码目录
└── README.md # 项目说明文档
核心目录说明
| 目录 | 作用 | 类比 |
|---|---|---|
src/main/java/ |
存放 Java 源代码 | 项目的"大脑",所有业务逻辑都在这里 |
src/main/resources/ |
存放资源文件 | 配置文件、静态资源等 |
src/main/webapp/ |
Web 应用根目录 | 相当于网站的"根目录" |
src/main/webapp/WEB-INF/ |
安全目录 | 浏览器无法直接访问此目录下的文件 |
pom.xml |
Maven 配置文件 | 项目的"身份证",包含依赖、插件等信息 |
webapp 目录的特殊性
src/main/webapp/
├── WEB-INF/
│ └── web.xml # 配置文件(浏览器无法直接访问)
├── css/ # 样式文件(浏览器可访问)
├── js/ # JS 文件(浏览器可访问)
├── error/ # 错误页面(浏览器可访问)
├── index.html # 主页(浏览器可访问)
├── student-query.html # 查询页(浏览器可访问)
└── student-save.html # 保存页(浏览器可访问)
为什么要有 WEB-INF 目录?
WEB-INF/是一个安全目录,浏览器无法直接访问里面的文件- 例如:
web.xml配置文件不能通过http://localhost:8080/WEB-INF/web.xml访问到 - 这保证了配置文件的安全性
- 只有通过 Servlet 转发或请求转发,才能访问 WEB-INF 下的资源
⚙️ 后端详解
pom.xml 核心配置
pom.xml 是 Maven 项目的核心配置文件,全称为 Project Object Model(项目对象模型)。
1. 项目坐标
xml
<groupId>org.example</groupId> <!-- 组织 ID,通常为公司或个人的域名反写 -->
<artifactId>java-web-demo</artifactId> <!-- 项目 ID,项目唯一标识 -->
<version>1.0-SNAPSHOT</version> <!-- 版本号,SNAPSHOT 表示开发中版本 -->
<packaging>war</packaging> <!-- 打包方式,war 表示 Web 应用 -->
为什么用 war 而不是 jar?
jar:SpringBoot 生态下的普通 Java 应用打包格式。SpringBoot 项目通常自带内置 Tomcat 服务器,打成 jar 包后可直接通过java -jar命令运行,无需额外配置 Tomcat。但传统的 Tomcat 服务器无法直接识别 jar 包war:Web Application Archive,专门用于 Java Web 应用的标准打包格式。包含了 Web 资源(HTML、CSS、JS 等)和 Java 代码,可以直接部署到 Tomcat 等 Web 服务器上运行
2. 依赖说明
xml
<dependencies>
<!-- Servlet API:Java Web 核心接口 -->
<!-- scope=provided 表示这个依赖只在编译时需要,运行时由服务器提供 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- Jetty 服务器:用于本地开发和测试 -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.53.v20231009</version>
</dependency>
<!-- Gson:JSON 序列化工具 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>
3. Jetty 插件
xml
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.53.v20231009</version>
<configuration>
<webApp>
<!-- 应用访问路径,/ 表示根路径 -->
<contextPath>/</contextPath>
<!-- web.xml 配置文件路径 -->
<descriptor>src/main/webapp/WEB-INF/web.xml</descriptor>
<!-- 静态资源目录 -->
<resourceBase>src/main/webapp</resourceBase>
</webApp>
<!-- 服务器端口 -->
<httpConnector>
<port>8080</port>
</httpConnector>
</configuration>
</plugin>
Jetty 插件的作用和运行时机:
| 问题 | 说明 |
|---|---|
| 是什么? | Maven 插件,用于启动嵌入式的 Jetty Web 服务器 |
| 什么时候运行? | 执行 mvn jetty:run 命令时启动 |
| 怎么工作的? | 1. 读取 pom.xml 配置2. 加载 web.xml 配置3. 初始化过滤器和 Servlet4. 启动 HTTP 服务器监听 8080 端口5. 处理 HTTP 请求 |
| 为什么要用? | 开发时不需要单独安装 Tomcat,直接用 Maven 就能启动服务器 |
4. War 打包插件
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<!-- 指定 Web 资源目录 -->
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<!-- 打包时排除某些文件 -->
<packagingExcludes>WEB-INF/classes/*.bak</packagingExcludes>
</configuration>
</plugin>
War 插件的运行时机:
| 问题 | 说明 |
|---|---|
| 什么时候运行? | 执行 mvn package 或 mvn install 时自动执行 |
| 做了什么? | 1. 编译 Java 源代码2. 将编译后的 class 文件和资源文件打包3. 生成 .war 文件到 target/ 目录 |
| 生成的 war 包能做什么? | 可以直接部署到 Tomcat 等服务器上运行 |
web.xml 配置详解
web.xml 是 Java Web 应用的部署描述符文件,用于配置 Web 应用的各种组件。
web.xml 是什么时候被读取的?
当 Web 服务器(如 Jetty、Tomcat)启动时,会:
- 找到
WEB-INF/web.xml文件 - 解析这个 XML 文件
- 按照配置创建过滤器、Servlet 等组件
- 建立 URL 映射关系
- 准备接收 HTTP 请求
1. 字符编码过滤器
xml
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.example.student.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
| 问题 | 说明 |
|---|---|
| 是什么? | 一个拦截器,在每个请求到达 Servlet 之前先执行 |
| 为什么需要? | 统一设置 UTF-8 编码,防止中文乱码 |
| 什么时候执行? | 每个请求都会执行,在 Servlet 之前 |
/* 是什么意思? |
匹配所有 URL,意味着所有请求都会经过这个过滤器 |
执行顺序:
浏览器请求 → CharacterEncodingFilter → CorsFilter → Servlet → 响应
2. CORS 跨域过滤器
xml
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>com.example.student.filter.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
什么是跨域问题?
浏览器的同源策略规定:如果网页的协议、域名、端口 有任何一个不同,就不能访问另一个服务器的资源。
如下是一个举例说明:
| 当前页面 URL | 请求的 API URL | 是否跨域 | 原因 |
|---|---|---|---|
| http://localhost:8080/ | http://localhost:8080/api/students | ❌ 不跨域 | 协议、域名、端口都相同 |
| http://localhost:3000/ | http://localhost:8080/api/students | ✅ 跨域 | 端口不同 |
解决方案:
在响应头中添加 CORS 相关的 HTTP 头,告诉浏览器允许跨域访问。
3. Servlet 配置
xml
<servlet>
<servlet-name>StudentServlet</servlet-name>
<servlet-class>com.example.student.servlet.BaseServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StudentServlet</servlet-name>
<url-pattern>/api/students/*</url-pattern>
</servlet-mapping>
Servlet 是什么?
Servlet 是 Java Web 的核心组件,用于处理 HTTP 请求并返回响应。相当于后端控制器。
| 配置项 | 说明 |
|---|---|
<servlet-name> |
Servlet 的名称,相当于给这个 Servlet 起个名字 |
<servlet-class> |
Servlet 的完整类名,指定了具体处理请求的 Java 类 |
<url-pattern> |
URL 匹配规则,哪些 URL 请求会交给这个 Servlet 处理 |
这个配置的含义:
- 所有以
/api/students/开头的请求,都会交给BaseServlet类处理 - 例如:
GET /api/students→ 查询学生列表GET /api/students/S000001→ 获取单个学生POST /api/students→ 新增学生PUT /api/students/S000001→ 更新学生DELETE /api/students/S000001→ 删除学生
4. 欢迎页面配置
xml
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
作用: 当用户访问 http://localhost:8080/ 时,服务器会自动返回 index.html 文件。
5. 会话配置
xml
<session-config>
<session-timeout>30</session-timeout>
</session-config>
什么是会话(Session)?
- HTTP 协议是无状态的,服务器不知道两次请求是否来自同一个用户
- Session 是服务器端的存储机制,用于保持用户状态
<session-timeout>30</session-timeout>表示用户 30 分钟内没有任何操作,会话将自动失效
6. 错误页面配置
xml
<error-page>
<error-code>404</error-code>
<location>/error/404.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/500.html</location>
</error-page>
作用: 当发生特定错误时,显示自定义的错误页面,而不是浏览器默认的错误页面。
| 错误码 | 含义 | 触发场景 |
|---|---|---|
| 404 | Not Found | 请求的资源不存在 |
| 500 | Internal Server Error | 服务器内部发生错误 |
Java 代码架构
整体架构图
浏览器发起请求
│
▼
┌─────────────────────────────────────────┐
│ 过滤器链(Filter Chain) │
│ 1. CharacterEncodingFilter(设置编码) │
│ 2. CorsFilter(处理跨域) │
└─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ BaseServlet(路由分发器) │
│ 根据 HTTP 方法和 URL 路径分发请求 │
└─────────────────────────────────────────┘
│
├───── GET /api/students ──────┐
├───── GET /api/students/{id} ─┤
├───── POST /api/students ─────┤
├───── PUT /api/students/{id} ─┤
└───── DELETE /api/students/{id}
│ │ │
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌────────────────┐
│List │ │Get │ │Create/Update/ │
│Servlet│ │Servlet│ │Delete Servlet │
└───────┘ └───────┘ └────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────┐
│ StudentDao(数据访问层) │
│ 使用内存 Map 模拟数据库操作 │
└─────────────────────────────────────────┘
│
▼
返回 JSON 响应给浏览器
包结构说明
| 包名 | 作用 | 包含的文件 |
|---|---|---|
model |
数据实体,定义数据结构 | Student.java |
dto |
数据传输对象,封装 API 响应格式 | ApiResponse.java, PageResult.java |
dao |
数据访问层,操作数据 | StudentDao.java |
filter |
过滤器,拦截请求 | CharacterEncodingFilter.java, CorsFilter.java |
servlet |
请求处理器,处理 HTTP 请求 | BaseServlet.java, StudentListServlet.java 等 |
util |
工具类,提供通用方法 | DateUtil.java |
请求处理流程(以查询学生列表为例)
请求:GET http://localhost:8080/api/students?name=张&pageNum=1&pageSize=10
-
浏览器发起请求
- 用户在查询页面输入"张",点击查询按钮
- 浏览器发送 GET 请求到后端
-
经过过滤器链
CharacterEncodingFilter:设置请求和响应的编码为 UTF-8CorsFilter:添加 CORS 响应头,允许跨域访问
-
到达 BaseServlet
- BaseServlet 的
service()方法被调用 - 解析 URL 路径:
pathInfo = null(因为访问的是/api/students,没有额外的路径) - 解析 HTTP 方法:
method = "GET" - 根据规则分发:
GET + pathInfo 为空→ 调用StudentListServlet.handle()
- BaseServlet 的
-
调用 StudentListServlet
- 解析请求参数:
name=张,pageNum=1,pageSize=10 - 调用
StudentDao.query()进行查询
- 解析请求参数:
-
DAO 层操作数据
- 遍历内存 Map 中的所有学生
- 过滤出姓名包含"张"的学生
- 按更新时间倒序排列
- 截取第 1 页的 10 条数据
- 返回分页结果
-
返回 JSON 响应
json{ "code": 200, "message": "success", "data": { "list": [{"id": "S000001", "name": "张三", ...}], "pageNum": 1, "pageSize": 10, "total": 1 } }
🎨 前端详解
前端技术栈介绍
Vue 2.x
什么是 Vue?
Vue 是一个渐进式 JavaScript 框架,用于构建用户界面。
本项目使用 CDN 方式引入 Vue:
html
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
CDN 方式 vs 工程化方式:
| 方式 | 说明 | 优点 | 缺点 |
|---|---|---|---|
| CDN | 通过 <script> 标签引入 |
简单、快速、无需构建 | 不适合大型项目 |
| 工程化 | 使用 Vue CLI + webpack | 适合大型项目、组件化开发 | 需要配置、学习成本高 |
Vue 的核心概念:
| 概念 | 说明 | 示例 |
|---|---|---|
new Vue() |
创建 Vue 实例 | new Vue({ el: '#app', data: {...} }) |
el |
挂载点,Vue 会接管这个 DOM 元素 | el: '#app' |
data |
响应式数据,数据变化时页面自动更新 | data: { name: '张三' } |
v-model |
双向数据绑定,表单输入和数据同步 | <input v-model="name"> |
methods |
方法集合,存放业务逻辑 | methods: { save() {...} } |
Element UI
什么是 Element UI?
Element UI 是一套基于 Vue 2 的桌面端组件库,提供了丰富的 UI 组件。
本项目引入方式:
html
<link
rel="stylesheet"
href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"
/>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
常用组件说明:
| 组件 | 标签 | 用途 |
|---|---|---|
| 表单 | <el-form> |
表单容器 |
| 表单项 | <el-form-item> |
表单项容器 |
| 输入框 | <el-input> |
文本输入 |
| 下拉框 | <el-select> |
下拉选择 |
| 按钮 | <el-button> |
按钮 |
| 表格 | <el-table> |
数据表格 |
| 分页 | <el-pagination> |
分页组件 |
| 消息提示 | ELEMENT.Message.success() |
成功提示 |
| 确认弹窗 | this.$confirm() |
二次确认对话框 |
Axios
什么是 Axios?
Axios 是一个HTTP 请求库,用于发送 AJAX 请求。
html
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Axios 的常用方法:
| 方法 | 用途 | 示例 |
|---|---|---|
axios.get() |
发送 GET 请求 | axios.get('/api/students') |
axios.post() |
发送 POST 请求 | axios.post('/api/students', data) |
axios.put() |
发送 PUT 请求 | axios.put('/api/students/S000001', data) |
axios.delete() |
发送 DELETE 请求 | axios.delete('/api/students/S000001') |
拦截器(Interceptor):
拦截器可以在请求发送之前或响应返回之后进行处理。
javascript
// 响应拦截器
api.interceptors.response.use(
function (response) {
// 请求成功,返回响应数据
return response;
},
function (error) {
// 请求失败,弹出错误提示
ELEMENT.Message.error("请求失败");
return Promise.reject(error);
},
);
index.html 主框架页
作用: 作为整个系统的主框架,包含左侧菜单和右侧内容区域。
页面布局
┌────────────────────────────────────────────┐
│ 左侧菜单 │ 右侧内容区 │
│ ┌────────────────────┐ │ ┌──────────────┐ │
│ │ Student Management │ │ │ │ │
│ ├────────────────────┤ │ │ iframe │ │
│ │ 🔍 学生信息查询 │ │ │ (嵌入子页面) │ │
│ │ ➕ 学生信息保存 │ │ │ │ │
│ └────────────────────┘ │ └──────────────┘ │
└────────────────────────────────────────────┘
iframe 工作原理
什么是 iframe?
iframe(内联框架)是 HTML 中的一个元素,用于在当前页面中嵌入另一个页面。
本项目的使用方式:
html
<iframe :src="currentUrl" :key="iframeKey" class="content-iframe"></iframe>
| 属性 | 说明 |
|---|---|
:src |
绑定当前加载的页面 URL |
:key |
Vue 的特殊属性,当 key 变化时强制重新渲染 iframe |
菜单切换逻辑:
javascript
handleMenuSelect: function (index) {
this.activeMenu = index; // 更新激活菜单
this.currentUrl = index; // 更新 iframe URL
this.iframeKey++; // 强制 iframe 重新加载
}
当用户点击菜单时:
index参数是被点击菜单的 URL(如student-query.html)- 更新
currentUrl,iframe 会加载新的页面 iframeKey++强制重新渲染 iframe,确保页面完全刷新
student-query.html 查询页面
作用: 展示学生信息查询功能,包含查询表单、数据表格和分页。
查询表单
html
<el-form :model="queryForm" inline class="query-form" size="small">
<el-form-item label="学号">
<el-input
v-model.trim="queryForm.studentId"
placeholder="请输入学号"
></el-input>
</el-form-item>
</el-form>
:model 是什么?
:model 是 Vue 的绑定语法,将表单与 queryForm 数据对象绑定。
v-model.trim 是什么?
v-model 是双向数据绑定,.trim 是修饰符,自动去除输入内容的首尾空格。
数据表格
html
<el-table :data="tableData" v-loading="loading" border size="small">
<el-table-column prop="id" label="学号" width="100"></el-table-column>
<el-table-column prop="name" label="姓名" width="150"></el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<template slot-scope="scope">
<span class="edit-link" @click="handleEdit(scope.row)">编辑</span>
<span class="delete-link" @click="handleDelete(scope.row)">删除</span>
</template>
</el-table-column>
</el-table>
:data 是什么?
:data 绑定表格的数据源,数据来自后端 API 的查询结果。
slot-scope 是什么?
slot-scope 是 Vue 的插槽语法,用于自定义表格列的内容。
scope.row 代表当前行的数据。
分页组件
html
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pagination.page"
:page-sizes="[10, 20, 50]"
:page-size="pagination.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total"
>
</el-pagination>
@size-change 是什么?
@size-change 是事件监听器,当用户切换每页条数时触发,调用 handleSizeChange 方法。
API 调用流程
javascript
fetchData: function () {
var params = {
pageNum: this.pagination.page,
pageSize: this.pagination.pageSize
};
// 添加查询条件(只添加非空条件)
if (this.queryForm.name) {
params.name = this.queryForm.name;
}
// 调用 API
api.get('/students', { params: params })
.then(function (response) {
// 更新表格数据和分页总数
self.tableData = response.data.data.list;
self.pagination.total = response.data.data.total;
});
}
student-save.html 保存页面
作用: 提供学生信息的保存功能,支持新增和编辑两种模式。
新增 vs 编辑模式
如何判断当前是哪种模式?
通过 URL 参数判断:
student-save.html→ 新增模式student-save.html?id=S000001→ 编辑模式
javascript
computed: {
isEditMode: function () {
return this.getUrlParameter('id') !== null;
}
}
表单校验
javascript
rules: {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' },
{ max: 50, message: '姓名不能超过50个字符', trigger: 'blur' }
],
age: [
{ required: true, message: '请输入年龄', trigger: 'blur' },
{ type: 'number', min: 0, max: 200, message: '年龄必须在0到200之间' }
]
}
校验规则说明:
| 规则 | 说明 |
|---|---|
required: true |
必填项 |
max: 50 |
最大长度 50 |
min: 0 |
最小值 0 |
trigger: 'blur' |
失去焦点时触发校验 |
trigger: 'change' |
值变化时触发校验 |
编辑模式数据回显
javascript
loadStudentData: function () {
api.get('/students/' + this.studentId)
.then(function (response) {
var student = response.data.data;
self.form.name = student.name;
self.form.age = student.age;
self.form.gender = student.gender;
self.form.description = student.description;
});
}
当进入编辑模式时,页面会自动调用 API 获取学生数据,并填充到表单中。
其他前端资源
css/common.css
公共样式文件,包含:
- 全局样式重置
- 布局样式(侧边栏、主内容区)
- 表单样式
- 表格样式
- 分页样式
js/api.js
Axios 实例配置文件,包含:
- 基础 URL 配置
- 请求超时设置
- 响应拦截器(统一处理错误提示)
error/404.html & 500.html
自定义错误页面:
404.html:页面不存在时的提示页面500.html:服务器错误时的提示页面
🚀 运行和部署
本地开发
1. 环境要求
| 软件 | 版本 | 说明 |
|---|---|---|
| JDK | 1.8 | Java 开发工具包 |
| Maven | 3.6+ | 项目构建工具 |
2. 启动项目
bash
# 进入项目目录
cd java-web-demo
# 启动 Jetty 服务器
mvn jetty:run
启动成功后,浏览器访问:http://localhost:8080/
3. 停止服务器
在终端中按 Ctrl + C 停止服务器。
打包部署
1. 打包成 WAR 文件
bash
# 执行打包命令
mvn package
打包完成后,会在 target/ 目录下生成 java-web-demo-1.0-SNAPSHOT.war 文件。
2. 部署到 Tomcat
- 将
.war文件复制到 Tomcat 的webapps/目录 - 启动 Tomcat 服务器
- 浏览器访问:
http://localhost:8080/java-web-demo-1.0-SNAPSHOT/
📖 学习路线建议
如果你是 Java Web 初学者,建议按照以下顺序学习本项目:
- 了解基础编程语言
- 学习 Java 语法
- 学习 html、css、js 前端知识
- 了解 Vue 和 Element UI 组件库
- 先了解 Java Web 基础概念
- 什么是 HTTP 协议
- 什么是 Servlet
- 什么是请求和响应
- 学习本项目 Java Web 的整体项目结构
- 了解
src/main/java/目录的后端代码结构 - 了解
src/main/webapp目录的前端代码结构 - 理解
pom.xml的作用 - 理解
web.xml的配置项
- 了解
- 阅读 Java 源代码
- 从
BaseServlet开始,理解请求分发逻辑 - 理解
web.xml中的配置项的作用 - 阅读
StudentDao,理解数据访问层
- 从
- 阅读前端代码
- 从
index.html,student-query.html,student-save.html开始,理解前端代码结构 - 理解 Vue 的基本用法
- 理解 Element UI 组件的使用
- 从
- 动手实践
- 尝试修改部分代码,观察效果
- 尝试添加新的功能,如"删除确认日志"
📝 总结
通过本项目,你可以学习到:
- ✅ Java Web 项目的标准结构
- ✅ 前后端分离的开发模式
- ✅ Java Web 的后端开发中:
- ✅ Servlet 如何处理 HTTP 请求
- ✅ web.xml 配置文件的各项配置(包括 Servlet、Filter、Listener 等)
- ✅ Java Web 的执行和 War 包打包
- ✅ Java Web 的前端开发中:
- ✅ Vue2 + Element UI 的前端开发
不少企业还留有很多 Java Web 需要维护的项目,希望这个项目能帮助你更好地理解传统的 Java Web 开发!
项目地址:Java Web Demo 可直接拉下来学习!