1. JavaWeb技术栈全景认知
作为一名从Servlet时代走过来的老Java开发者,我至今记得第一次在Tomcat上成功跑通JSP页面时的兴奋。JavaWeb作为企业级开发的中流砥柱,其技术生态经历了从单体架构到微服务的完整演进历程。让我们先建立整体认知框架:
JavaWeb开发本质上是在Java技术栈基础上构建B/S架构应用的技术集合,核心包含三大标准组件:
- Servlet:处理HTTP请求响应的基础API(javax.servlet包)
- JSP:动态页面模板技术(本质会被编译为Servlet)
- JDBC:数据库连接标准接口
现代JavaWeb项目通常采用分层架构设计:
code复制表示层(JSP/Thymeleaf)
↓
控制层(Servlet/Spring MVC)
↓
服务层(Spring Core)
↓
持久层(JDBC/MyBatis/Hibernate)
↓
数据库(MySQL/Oracle)
关键认知:当前主流开发已从原生Servlet/JSP转向Spring Boot体系,但理解底层机制仍是进阶基础。就像学开车要先懂离合原理,哪怕现在都是自动挡。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开发环境搭建实战
2.1 工具链选型建议
- IDE:IntelliJ IDEA Ultimate版(社区版对Web支持有限)
- 构建工具:Maven 3.6+(Gradle亦可但Maven资料更丰富)
- 应用服务器:Tomcat 9.x(注意JDK版本兼容性)
- 数据库:MySQL 8.0(生产推荐Percona分支)
2.2 项目骨架创建
通过IDEA新建Maven项目时,建议使用maven-archetype-webapp原型:
xml复制<!-- pom.xml必须包含的依赖 -->
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
项目目录结构规范:
code复制src
├── main
│ ├── java # Java源代码
│ ├── resources # 配置文件
│ └── webapp # WEB-INF和静态资源
│ ├── WEB-INF
│ │ └── web.xml # 部署描述符
│ └── index.jsp # 欢迎页
避坑提示:webapp目录必须直接放在main下,某些IDE会错误生成src/main/webapp/WEB-INF/web.xml路径导致404。
3. Servlet核心机制解析
3.1 生命周期深度剖析
每个Servlet都遵循严格的生命周期:
- 初始化:容器调用
init()方法(仅一次) - 服务:针对每个请求调用
service()方法- 默认实现会根据HTTP方法路由到
doGet()/doPost()
- 默认实现会根据HTTP方法路由到
- 销毁:容器关闭时调用
destroy()方法
典型代码实现:
java复制@WebServlet("/hello") // 注解方式注册
public class HelloServlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("Servlet初始化...");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<h1>Hello World!</h1>");
}
}
3.2 请求响应对象妙用
-
HttpServletRequest:获取请求参数、头部、会话等
java复制String username = request.getParameter("user"); Cookie[] cookies = request.getCookies(); HttpSession session = request.getSession(); -
HttpServletResponse:设置响应状态、内容、重定向
java复制response.setStatus(HttpServletResponse.SC_OK); response.sendRedirect("/newPath"); response.addCookie(new Cookie("token", "abc123"));
性能技巧:避免在Servlet中直接拼接HTML,应使用JSP或模板引擎分离视图逻辑。
4. JSP技术内幕与最佳实践
4.1 编译原理揭秘
JSP本质是Servlet的语法糖,编译过程:
code复制hello.jsp
→ 翻译为hello_jsp.java
→ 编译为hello_jsp.class
通过查看Tomcat生成的.java文件(位于work目录),可以理解JSP的底层实现机制。
4.2 脚本元素全解
jsp复制<%@ page contentType="text/html;charset=UTF-8" %> <!-- 指令 -->
<%! int count = 0; %> <!-- 声明 -->
<%= new java.util.Date() %> <!-- 表达式 -->
<% if(count > 10) { %> <!-- 脚本段 -->
<p>访问过多</p>
<% } %>
4.3 EL表达式与JSTL
现代项目应避免直接使用JSP脚本,推荐组合:
jsp复制<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
</tr>
</c:forEach>
重要认知:JSP的
${}实际上是调用了PageContext.findAttribute()方法,按page→request→session→application顺序查找属性。
5. 会话管理实战策略
5.1 Cookie与Session对比
| 特性 | Cookie | HttpSession |
|---|---|---|
| 存储位置 | 客户端 | 服务端 |
| 安全性 | 较低(可篡改) | 较高(仅存session id) |
| 容量限制 | 4KB左右 | 受服务器内存限制 |
| 生命周期 | 可设置过期时间 | 默认会话结束失效 |
5.2 分布式会话方案
在集群环境中,传统Session会失效,解决方案:
- Session复制:Tomcat集群配置
xml复制<!-- server.xml --> <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> - 集中存储:Redis + Spring Session
java复制@EnableRedisHttpSession public class SessionConfig { @Bean public LettuceConnectionFactory connectionFactory() { return new LettuceConnectionFactory(); } }
6. 过滤器与监听器高级应用
6.1 过滤器链实现原理
java复制@WebFilter("/*")
public class LogFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
long start = System.currentTimeMillis();
chain.doFilter(req, res); // 关键:调用下一个过滤器
long cost = System.currentTimeMillis() - start;
System.out.println("请求耗时:" + cost + "ms");
}
}
6.2 监听器典型场景
- ServletContextListener:应用启动时加载全局配置
java复制public class AppInitListener implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { String configPath = sce.getServletContext() .getInitParameter("configLocation"); // 初始化数据库连接池等 } }
7. 现代JavaWeb技术演进
虽然现在直接使用原生Servlet/JSP的场景越来越少,但理解这些基础对掌握Spring MVC等框架至关重要。建议学习路线:
- 掌握原生API → 2. 学习Spring MVC → 3. 过渡到Spring Boot
在IDEA中创建完整JavaWeb项目时,可以尝试:
- 实现用户登录(Session管理)
- 增加过滤器处理字符编码
- 使用JSTL展示数据库数据
- 打包为WAR部署到Tomcat
我曾见过不少开发者直接跳到底层学习,结果在使用Spring时遇到问题无法深度排查。就像修车师傅必须懂发动机原理一样,扎实的JavaWeb基础会让你在框架使用中游刃有余。
