servlet 的作用什么?
简单来讲:servlet就是一个小服务器,主要作用就是调用java代码,因java代码也存在一个分层,如让java代码来去调用数据库等
servlet的作用就是当服务器遇到一个动态请求时,那么此刻就需要将该请求解析后然后传递后servlet,servlet负责调用java代码,让代码去调用数据库等
为什么要使用servlet?
我们现在有这样的一个需求,如果我们要在一个网络上查看或写评论,像这类事情我们需要该怎么做?
我们知道传统的服务器,是可以将静态页面(html,js,css等)直接放在服务器上,假设客户端发送的是一个静态页面,那么服务器就可以直接将其返回,而如果是要获取这种资料放在数据库中的,那么就需要调用数据苦,而服务器是不能直接调用数据库的,于是就有了servlet
浏览器请求Servlet详细流程图
浏览器第一次请求Servlet时:
1.tomcat首先先获取到servlet的资源,也就是HelloServlet
2.通过在web.xml文件中查找servlet,也就是浏览器请求路径<url-pattern>/helloServlet</url-pattern>
3.如果找到客户端请求路径rul-pattern,就会找到servlet-name:HelloServlet
4.因tomcat下有一个hashMap<id, servlet>,通过其类名(HelloServlet)也就是ID(因ID是唯一),在hashMap中进行查找
5.如果没有找到该servlet-name对应的id,即没有这个Servlet的实例
6.那么就会通过到servlet-name,得到servlet-calss就是类HelloServlet的全路径(servlet-class)
7.使用反射技术,将servlet实例化,调用init()方法,并添加到HashMap中
注意:类的加载和对象实例是不同的概念
类加载是:
1.new一个对象实例时
2.
3.调用类的静态成员时,该类会被加载,其父类也会被加载
浏览器第二次请求及其以后请求:
1.tomcat首先先获取到servlet的资源,也就是HelloServlet
2.通过在web.xml文件中查找servlet,也就是浏览器请求路径<url-pattern>/helloServlet</url-pattern>
3.通过其请求路径,得到其类名。因tomcat下有一个hashMap<id, servlet>,通过其类名(HelloServlet)也就是ID(因ID是唯一),在hashMap中进行查找
4.如果查询到,则直接调用该Servlet中的servlet()方法
5.结果显示
注意:Servlet 是一个单例,也就是说不管http请求多少次,其Servlet被Tomcat只创建一个servlet实例对象
我们可以尝试这样一个案例:在servlet中创建一个int count属性,在servlet()方法中count++;
接着打印出来,就可以看到每次都会++
但我们知道如果http请求每请求一次,是创建不同的servlet实例对象,那么调用时count是不会每次++的
Servlet的生命周期
初始化(init) 请求每次被调用(service) 结束期
注意:在初始化时,其图片是有些问题,在初始化时是要先判断Servlet实例是否存在,不存在时则是会Tomcat下维护的HashMap中,加载类并创建实例
类的加载和对象实例是不同的概念?
初始化是指:tomcat加载Servlet,加载完成后,tomcat会把所继承Servle的类,通过反射进行实例化对象,将Servlet的实例化对象放入到Tomcat下的HashMap中,并调用该实例化对象的init()方法,该方法只会被调用一次。tomcat再下面几种情况状态Servlet
1.在tomcat启动时会自动装载某些Servlet实例,实现这个方法需要在web.xml中添加
<Servlet>标签下添加<load-on-startup>1</load-on-startup>
数字1:表示tomcat启动时先启动哪个server实例后启动哪个
2.未在web.xml配置启动加载Servlet时,Servlet第一次接收hppt请求时,会调用init()方法
3.当servlet容器(也就是服务器)Redeploy或Restart seve后(因Redeploy会将tomcat加载到HashMap中的servlet实例全部删除),Servlet第一次接收hppt请求时,调用init()方法
前提是未在web.xml未配置<load-on-startup>1</load-on-startup>
如果配置了<load-on-startup>1</load-on-startup> ,则会直接就启动
service()处理浏览器请求阶段 service()方法:
1.每收到一个http请求,服务器就会产生一个新的Servlet线程去处理
2.tomcat会创建一个用来封装HTTP请求的 ServletRequest 对象 和 一个代表HTTP响应的 ServletResponse 对象
3.然后调用Servlet的service()方法并将请求和响应 对象 作为参数传递进去
重点:
public void service(ServletRequest servletRequest, ServletResponse servletResponse)
为什么要使用服务器?服务器的作用是什么?
Tomcat(Servlet容器(也就是服务器))最重要的一点是:
(1)在接收到客户端发送的HTTP请求时,是要将HTPP请求的内容进行解析,然后封装成实现了ServletRequest接口的类,发送给Servlet,Servlet接收后,通过其ServletRequest中的方法拆解,得到其HTTP请求的内容
(2)而返回时一致,将返回给客户端的响内容封装成是实现ServletResponse接口的类,发送给Tomcat,Tomcat再将其内容解析再封装成HTTP响应返回
(3)再解析HTTP请求和封装,这个过程的难度是非常大的,而我们一般也是无法做到的,而这就是服务器最重要的作用,服务器也称作为Servlet容器,Tomcat就属于服务器的其中一种类型
终止阶段 destory()方法:
1.关闭Tomcat
2.结束web项目
3.Redeploy或Restart seve时
使用注解来配置文件
@WebServlet
使用注解就相当于是在web.xml中配置文文件,而注解本身就相当于一个类,其是将配置文件信息放在其类中,通过tomcat扫描出来
使用注解配置文件的运行原理
1、tomcat在运行Servlet时,通过IO流会先将java代码进行扫描一遍是否存在注解,
2、存在注解时,进行获取到该存在注解类的URL全路径
3、通过全路径,使用反射技术,获取到该类的Class
4、接着拿到该类的注解中url路径
5、如果是第一次,tomcat会与浏览器发出Servlet请求的url路径进行匹配,如果匹配上,则将其实例添加到tomcat维护的HashMap中
//相当于tomcat下维护的HashMap,用来添加所有Servlet对象实例,并控制操作
private final static HashMap<String, Object> hm = new HashMap<>();
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//1.首先要得到扫描的包 路径 通过IO流来扫描,进而得到某个类的全路径
String classAllPath = "com.hspedu.servlet.annotation.OkServlet";
//2.通过全路径,得到OkServlet的Class对象
Class<?> aClass = Class.forName(classAllPath);
//3.Class对象获取到OkServlet的annotation(注解)
WebServlet annotation = aClass.getAnnotation(WebServlet.class);
//打印出注解的信息
System.out.println(annotation);
//4.得到urlPatterns的路径集合(也就是浏览器访问Servlet的路径集合)
String[] strings = annotation.urlPatterns();
//5.获取单个urlPattern
for (String url : strings) {
System.out.println("url= " + url);
}
//使用浏览器发出Servlet请求路径,如果和注解中url进行匹配,如果匹配上
// 如果是第一次,tomcat就会创建一个OkServlet实例,放入到HashMap中
//6.创建OkServlet实例
Object instance = aClass.newInstance();
System.out.println("instance= " + instance);//instance此刻就是OkServlet实例
hm.put("OkServlet", instance);
System.out.println(hm);
}