Servlet总结
Servlet 总结
什么是 Servlet?
Servlet 是 Java EE 规范中的核心组件,它是一种运行在服务器端的 Java 程序,主要用于处理客户端请求并作出响应。
Servlet 的执行过程?
- 请求发送:客户端发送请求到服务器端。
- 请求转发:服务器端根据
web.xml文件中的 Servlet 相关配置信息,将客户端请求转发到相应的 Servlet。 - 业务处理:Servlet 根据
request对象中封装的用户请求与数据库进行交互;返回数据之后,Servlet 将数据封装到response对象中。 - 响应返回:控制权从 Servlet 重新回到服务器端,服务器端将响应信息返回给客户端,并跳转到相应的页面。
Servlet 的生命周期?
- 加载和实例化:在第一次请求 Servlet 时,Servlet 容器将会创建 Servlet 实例。
- 初始化:Servlet 容器加载完成 Servlet 之后,必须进行初始化,此时
init()方法将被调用。 - 服务请求:Servlet 初始化之后,处于响应请求的就绪状态。此时如有客户端请求发送,就会调用 Servlet 实例的
service()方法,并且根据用户的请求方式,调用doPost()或者doGet()方法。 - 销毁:最后,Servlet 容器负责将 Servlet 实例进行销毁,调用
destroy()方法实现。
Servlet 与 JSP 的关系及区别?
- 关系:Servlet 是 JSP 的基础,JSP 是 Servlet 技术的扩展。JSP 运行之前首先会被编译为一个 Servlet。
- 区别:JSP 侧重于视图(View)展示;Servlet 主要用于控制业务逻辑(Controller)。
Servlet API 中的 forward() 与 redirect() 的区别?
| 特性 | 请求转发 (forward) | 重定向 (redirect) |
|---|---|---|
| 实现方法 | Request 对象的方法 | Response 对象的方法 |
| 执行位置 | 服务器端执行 | 客户端浏览器执行 |
| 请求次数 | 1 次请求 | 2 次请求 |
| 地址栏变化 | 不会改变 | 发生改变 |
| 数据共享 | 始终在同一个 Request 域中,可共享资源 | 第二次请求将丢失第一次 Request 中的资源 |
| 性能 | 优于重定向 | 相对较低 |
Servlet 如何同时处理多个请求?
Servlet 采用多线程来处理多个请求的同时访问。Servlet 容器通过线程池来管理维护服务请求。所谓线程池,相当于数据库连接池,实际上是等待执行代码的一组线程,叫做工作者线程。Servlet 容器通过一个调度线程来管理工作者线程。
- 当容器收到一个 Servlet 的访问请求,调度者线程就从线程池中选出一个工作者线程,将用户请求传递给该线程,然后由该线程处理 Servlet 的
service()方法; - 当这个线程在执行的时候,容器收到一个新的请求,调度者线程再次从线程池中选出一个新的工作者线程;
- 当容器同时收到对同一个 Servlet 的多个请求时,那么 Servlet 的
service()方法将在多线程中并发执行。
注:
- Servlet 容器默认采用单实例多线程的方式来处理请求。这样减少了产生 Servlet 实例的开销,提升了对请求的响应时间。
- 对于 Tomcat 容器来讲,可以在其
server.xml中通过<Connector>配置设置线程池中的线程数目。
问题:Servlet 可不可以采用多实例多线程?或者多实例单线程?
如何开发线程安全的 Servlet?
Servlet 容器采用多线程来处理请求,提高性能的同时也造成了线程安全问题。要开发线程安全的 Servlet 应该从以下几个方面进行:
- 变量的线程安全:多线程并不共享局部变量,所以我们要尽可能的在 Servlet 中使用局部变量。
- 代码块的线程安全:使用同步块
synchronized,防止可能调用的代码块冲突。但是要注意的是,要尽可能缩小同步代码的范围,不要在service()方法和响应方法上直接使用同步,这会严重影响性能。 - 属性的线程安全:注意
ServletContext、HttpSession、ServletRequest对象中属性的安全性。 - 使用同步集合:使用
Vector代替ArrayList,使用Hashtable代替HashMap。 - 避免自定义线程:不要在 Servlet 中创建自己的线程来完成某个功能。Servlet 本身就是多线程的,如果再创建新的线程,将会导致线程执行复杂化,出现线程安全问题。
- 外部对象互斥:在多个 Servlet 中,对外部对象(比如文件)进行修改操作一定要加锁,做到互斥访问。
SingleThreadModel 接口?
javax.servlet.SingleThreadModel 接口是一个标识接口。如果一个 Servlet 实现了这个接口,那 Servlet 容器将保证在一个时刻仅有一个线程可以在给定的 Servlet 实例的 service() 方法中执行,将其他所有请求进行排队。
如何实现 Servlet 的单线程模式?
实现方法(针对 JSP):
<%@ page isThreadSafe="false" %>说明:
- 本文内容基于传统 Servlet 规范整理。
SingleThreadModel接口已在 Servlet 2.4 版本中被标记为 deprecated(废弃),并在 Servlet 3.0 版本中被移除。现代开发中不建议使用该模式,应通过优化代码逻辑(如避免使用实例变量)来保证线程安全。- 关于同步集合的建议(如 Vector/Hashtable)属于早期 Java 并发编程实践,现代开发推荐使用
java.util.concurrent包下的并发容器。
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
本文地址:https://1diff.fun/archives/servlet-zong-jie.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。