Servlet
首先javaWeb肯定是脱离不了Servlet,在以前学习之后很多都忘了,在这里特地整理一下。
Servlet简介
Servlet是sun公司提供的一门用于开发动态web资源的技术。
Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
1、编写一个Java类,实现servlet接口。
2、把开发好的Java类部署到web服务器中。
按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet
Servlet接口的结构:
图片来自慕课网(https://www.imooc.com/video/5537)
Servlet的运行过程【生命周期】
Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
②装载Servlet类并创建该Servlet的一个实例对象。
③调用Servlet实例对象的init()方法。【注意,init()方法仅在服务器装载Servlet时才由服务器执行一次】
④创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。【每次客户向服务器发请求时,服务器就会调用Service()方法。 】
⑤WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
HttpServlet
HttpServlet指能够处理HTTP请求的servlet,它在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大。因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。
【注意:service(HttpServletRequest, HttpServletResponse)方法是HttpServlet类定义的方法,是受保护的(protected),主要作用是接受标准的Http请求(HttpServletRequest),并根据请求方式不同分发到不同的doXXX(HttpServletRequest, HttpServletResponse)方法。原文:https://blog.csdn.net/fantasysxan/article/details/80264250 】
HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。
【若service()、doPost()和doGet()方法同时存在,只会执行service方法】
因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法。
Servlet的线程安全问题
servlet不是线程安全的,当Tomcat接收到Client的HTTP请求时,Tomcat从线程池中取出一个线程,之后找到该请求对应的Servlet对象并进行初始化,之后调用service()方法。要注意的是每一个Servlet对象再Tomcat容器中只有一个实例对象,即是单例模式。如果多个HTTP请求请求的是同一个Servlet,那么着两个HTTP请求对应的线程将并发调用Servlet的service()方法。
例子: 一、当一个变量写在doPost或者doGet里面时,属于局部变量,是放在栈中,属于线程独享的,此时不会有线程安全问题
二、如果在servlet实现类里写了一个全局变量的话,那么此时就会有线程安全问题了,所以在编写Servlet的时候,如果并发访问某一个资源(变量,集合等),就会存在线程安全问题。
(servlet线程安全的解决方法:)
{
1、加锁,对变量加锁,这就是普通线程安全问题的解决方法
2、Sun公司提供了一个接口SingleThreadModel,原理是每次调用就实例化一个servlet对象,(已过时)
3、避免使用实例变量,采用局部变量的形式
}
Servlet的确已经能够帮我们完成所有的工作了,但是现在的web应用很少有直接将交互全部页面都用servlet来实现,而是采用更高效的MVC框架来实现。这些MVC框架基本的原理都是将所有的请求都映射到一个Servlet(DispatcherServlet),然后去实现service方法,这个方法也就是MVC框架的入口。
【参考:Spring MVC是如何逐步简化Servlet的编程的:https://www.cnblogs.com/winterfells/p/8476759.html】
【在我的博文中也有介绍到spring与Servlet相关联的:https://blog.nowcoder.net/n/f718a54c4a7e4ed69428809c24a18037】
Servlet路径(相对路径和绝对路径):
path是通过request.getContextPath获取的
参考:
https://blog.csdn.net/zj12352123/article/details/80576748【比较全面,谈到了servlet介绍以及多线程安全问题】
https://www.cnblogs.com/chanshuyi/p/5052426.html【servlet的线程安全问题】