JavaWeb 从入门到面试:Tomcat、Servlet、JSP、过滤器、监听器、分页与Ajax全面解析
JavaWeb 从入门到面试:Tomcat、Servlet、JSP、过滤器、监听器、分页与Ajax全面解析
一、概述
JavaWeb 是使用 Java 技术栈开发 Web 应用程序的重要领域,涵盖了从服务器搭建到前端交互的完整技术链。本文将系统讲解 JavaWeb 的核心知识点,并穿插面试常见问题,帮助你从入门到应对面试。
完整内容:
- Tomcat 与 JavaEE 入门
- Servlet 基础与生命周期
- JSP 原理与使用
- 过滤器与监听器
- 分页实现原理
- Ajax 与前端交互
- 项目结构与设计模式
二、Tomcat 与 JavaEE 入门
1. 什么是 Tomcat?
Tomcat 是一个开源的 Web 服务器和 Servlet 容器,由 Apache 基金会维护。它是 JavaEE 中 Web 规范的实现之一,用于部署和运行 Servlet 和 JSP。
2. 安装与启动 Tomcat
- 下载 Tomcat 并解压
- 配置环境变量
CATALINA_HOME
- 启动:运行
bin/startup.bat
(Windows)或bin/startup.sh
(Linux/Mac) - 访问:http://localhost:8080
3. Web 应用目录结构
ProjectName
│
├── WEB-INF
│ ├── web.xml (部署描述文件)
│ ├── classes (编译后的Java类)
│ └── lib (依赖的JAR包)
│
├── META-INF
│ └── MANIFEST.MF (可选的清单文件)
│
└── 静态资源 (HTML, CSS, JS,图片等)
4. JavaEE 简介
JavaEE(Java Platform, Enterprise Edition)是一套用于企业级应用开发的标准规范,包括 Servlet、JSP、EJB、JPA 等。Tomcat 实现了 Servlet 和 JSP 规范,是轻量级的 JavaEE 容器。
5. 常见面试题
- Tomcat 的默认端口是什么?如何修改?
- Tomcat 如何部署项目?有哪几种方式?
- Tomcat 与 Nginx 有什么区别?
三、Servlet
1. 什么是 Servlet?
Servlet 是运行在服务器端的 Java 程序,用于处理客户端(如浏览器)的请求并生成响应。它是 JavaWeb 的核心技术之一。
2. Servlet 的生命周期
- 初始化:
init()
方法被调用,只执行一次 - 处理请求:
service()
方法根据请求类型调用doGet()
、doPost()
等 - 销毁:
destroy()
方法在 Servlet 被卸载时调用
3. 编写一个简单的 Servlet
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("text/html;charset=UTF-8");PrintWriter out = response.getWriter();out.println("<h1>Hello, Servlet!</h1>");}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}
}
4. Servlet 配置方式
注解方式(推荐):
@WebServlet(name = "HelloServlet", urlPatterns = {"/hello", "/hi"})
web.xml 配置方式:
<servlet><servlet-name>HelloServlet</servlet-name><servlet-class>com.example.HelloServlet</servlet-class>
</servlet>
<servlet-mapping><servlet-name>HelloServlet</servlet-name><url-pattern>/hello</url-pattern>
</servlet-mapping>
5. 请求和响应对象
- HttpServletRequest:获取客户端请求信息
- HttpServletResponse:向客户端发送响应
6. 会话管理
- Cookie:客户端会话技术
- Session:服务器端会话技术
// 获取Session
HttpSession session = request.getSession();// 设置Session属性
session.setAttribute("username", "john");// 获取Session属性
String username = (String) session.getAttribute("username");
7. 常见面试题
- Servlet 是线程安全的吗?如何处理并发?
- Servlet 和 JSP 的区别是什么?
- 如何实现 Servlet 之间的跳转?
- GET 和 POST 请求的区别?
- 重定向和转发的区别?
四、JSP
1. 什么是 JSP?
JSP(JavaServer Pages)是一种动态网页技术,允许在 HTML 中嵌入 Java 代码。JSP 最终会被编译为 Servlet 执行。
2. JSP 的基本语法
- 脚本片段:
<% Java代码 %>
- 表达式:
<%= 表达式 %>
- 声明:
<%! 变量或方法 %>
- 指令:
<%@ page import="java.util.List" %>
3. JSP 的隐含对象
JSP 提供了9个隐含对象,无需声明即可使用:
request
、response
、out
、session
、application
、pageContext
、config
、page
、exception
4. JSP 与 Servlet 的协作
通常使用 Servlet 处理业务逻辑,JSP 负责显示视图:
// 在Servlet中设置属性
request.setAttribute("message", "Hello World");
request.getRequestDispatcher("/result.jsp").forward(request, response);
<!-- 在JSP中获取属性 -->
<p><%= request.getAttribute("message") %></p>
5. EL 表达式和 JSTL
EL表达式(Expression Language):
<p>${message}</p>
<p>${user.name}</p>
JSTL(JSP Standard Tag Library):
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><c:if test="${not empty user}"><p>欢迎, ${user.name}!</p>
</c:if><c:forEach items="${users}" var="user"><p>${user.name} - ${user.email}</p>
</c:forEach>
6. 常见面试题
- JSP 的生命周期是怎样的?
- JSP 有哪些作用域?区别是什么?
- 如何避免 JSP 中的 Java 代码过多?
- EL 表达式的作用是什么?
- JSTL 有哪些常用的标签?
五、过滤器和监听器
1. 过滤器(Filter)
1.1 什么是过滤器?
过滤器是介于客户端和服务器资源之间的一道过滤网,可以对请求和响应进行统一处理。
1.2 过滤器的应用场景
- 权限验证
- 字符编码过滤
- 日志记录
- 数据压缩
1.3 编写一个过滤器
@WebFilter("/*")
public class EncodingFilter implements Filter {public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");chain.doFilter(request, response);}public void init(FilterConfig fConfig) throws ServletException {}public void destroy() {}
}
1.4 过滤器链
多个过滤器可以形成一个过滤器链,按照 web.xml 中配置的顺序执行。
2. 监听器(Listener)
2.1 什么是监听器?
监听器用于监听 Web 应用中某些对象创建、销毁或属性变化等事件。
2.2 常用的监听器接口
ServletContextListener
:监听上下文创建和销毁HttpSessionListener
:监听会话创建和销毁ServletRequestListener
:监听请求创建和销毁
2.3 编写一个监听器
@WebListener
public class AppContextListener implements ServletContextListener {public void contextInitialized(ServletContextEvent sce) {System.out.println("Web应用启动");// 初始化数据库连接池等资源}public void contextDestroyed(ServletContextEvent sce) {System.out.println("Web应用关闭");// 释放资源}
}
3. 常见面试题
- 过滤器有哪些作用?执行流程是怎样的?
- 过滤器和拦截器的区别?
- 监听器有哪些类型?分别监听什么?
- 如何实现用户登录验证的过滤器?
六、分页实现
1. 分页的必要性
当数据量很大时,一次性查询所有数据会降低性能,分页可以提高查询效率和用户体验。
2. 分页的实现方式
2.1 数据库分页(推荐)
MySQL:
SELECT * FROM products LIMIT 0, 10; -- 第1页,每页10条
SELECT * FROM products LIMIT 10, 10; -- 第2页,每页10条
Oracle:
SELECT * FROM (SELECT t.*, ROWNUM rn FROM (SELECT * FROM products ORDER BY create_time DESC) t WHERE ROWNUM <= 20
) WHERE rn > 10;
2.2 内存分页
先查询所有数据,然后在内存中进行分页(不推荐大数据量使用)。
3. 分页封装类
public class Page<T> {private int pageNo; // 当前页码private int pageSize; // 每页大小private int totalCount; // 总记录数private int totalPage; // 总页数private List<T> list; // 当前页数据// 构造方法、getter和setterpublic Page(int pageNo, int pageSize) {this.pageNo = pageNo;this.pageSize = pageSize;}public int getTotalPage() {return (int) Math.ceil((double) totalCount / pageSize);}
}
4. 分页查询示例
public Page<Product> getProducts(int pageNo, int pageSize) {Page<Product> page = new Page<>(pageNo, pageSize);// 查询总记录数int totalCount = productDao.getTotalCount();page.setTotalCount(totalCount);// 查询当前页数据int start = (pageNo - 1) * pageSize;List<Product> products = productDao.getProducts(start, pageSize);page.setList(products);return page;
}
5. 前端分页展示
<!-- 分页控件 -->
<div class="pagination"><c:if test="${page.pageNo > 1}"><a href="?pageNo=1">首页</a><a href="?pageNo=${page.pageNo - 1}">上一页</a></c:if><c:forEach begin="1" end="${page.totalPage}" var="i"><c:choose><c:when test="${i == page.pageNo}"><span class="current">${i}</span></c:when><c:otherwise><a href="?pageNo=${i}">${i}</a></c:otherwise></c:choose></c:forEach><c:if test="${page.pageNo < page.totalPage}"><a href="?pageNo=${page.pageNo + 1}">下一页</a><a href="?pageNo=${page.totalPage}">末页</a></c:if>
</div>
6. 常见面试题
- 分页的实现原理是什么?
- 数据库分页和内存分页的区别?
- 如何优化大数据量的分页查询?
- 什么是深分页问题?如何解决?
七、Ajax
1. 什么是 Ajax?
Ajax(Asynchronous JavaScript and XML)是一种创建交互式网页应用的网页开发技术,可以在不重新加载整个页面的情况下与服务器交换数据。
2. 原生 JavaScript 实现 Ajax
function loadData() {var xhr = new XMLHttpRequest();xhr.open('GET', 'api/data', true);xhr.onreadystatechange = function() {if (xhr.readyState == 4 && xhr.status == 200) {var data = JSON.parse(xhr.responseText);// 处理数据updateUI(data);}};xhr.send();
}
3. jQuery 实现 Ajax
$.ajax({url: 'api/data',type: 'GET',dataType: 'json',success: function(data) {// 处理成功返回的数据updateUI(data);},error: function(xhr, status, error) {// 处理错误console.error(error);}
});
4. 服务器端处理 Ajax 请求
@WebServlet("/api/data")
public class DataServlet extends HttpServlet {protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {response.setContentType("application/json;charset=UTF-8");List<Product> products = productService.getAllProducts();// 使用Gson等库将对象转换为JSONGson gson = new Gson();String json = gson.toJson(products);PrintWriter out = response.getWriter();out.print(json);out.flush();}
}
5. 表单异步提交
$('#productForm').submit(function(e) {e.preventDefault();$.ajax({url: 'api/products',type: 'POST',data: $(this).serialize(),success: function(response) {alert('保存成功');loadData(); // 重新加载数据},error: function() {alert('保存失败');}});
});
6. 常见面试题
- Ajax 的原理是什么?
- Ajax 的优缺点是什么?
- 什么是跨域问题?如何解决?
- JSONP 的实现原理是什么?
八、项目结构与设计模式
1. 分层架构
典型的三层架构:
- 表示层(Web层):Servlet、JSP、过滤器、监听器
- 业务逻辑层(Service层):处理业务逻辑
- 数据访问层(DAO层):数据库操作
2. MVC 设计模式
- Model(模型):数据和业务逻辑,如JavaBean、Service、DAO
- View(视图):用户界面,如JSP、HTML
- Controller(控制器):处理用户请求,如Servlet
3. 工厂模式在DAO层中的应用
public class DAOFactory {public static UserDAO getUserDAO() {return new UserDAOImpl();}public static ProductDAO getProductDAO() {return new ProductDAOImpl();}
}
4. 数据库连接池
使用连接池管理数据库连接,提高性能:
// 使用DBCP连接池
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test");
dataSource.setUsername("root");
dataSource.setPassword("password");
5. 常见面试题
- MVC 模式是什么?有什么优点?
- 为什么要使用分层架构?
- 什么是DAO模式?
- 数据库连接池的作用是什么?
九、总结
本文全面介绍了 JavaWeb 开发的核心技术,从基础的 Tomcat 配置到高级的 Ajax 交互,涵盖了 JavaWeb 开发的各个方面。掌握这些知识不仅能够进行 JavaWeb 项目开发,也能应对大多数 JavaWeb 相关的面试问题。
学习建议:
- 理论与实践相结合,多动手写代码
- 理解每个技术的原理和适用场景
- 关注性能优化和最佳实践
- 学习相关的框架如 Spring、Spring MVC、MyBatis 等
进一步学习方向:
- Spring 框架家族(Spring MVC, Spring Boot, Spring Cloud)
- 持久层框架(MyBatis, Hibernate)
- 前端框架(Vue.js, React, Angular)
- 分布式和微服务架构
希望本文能为你打开 JavaWeb 开发的大门,祝你学习顺利!