Servlet实现机制

jsp/servlet实现机制

在进行原理分析之前,我们先进行对比分析:

在JSP出现之前,为了实现动态网页的效果,服务器端利用 Servlet 的输出流向客户端发送HTML标签以及HTML页面中的内容,但是在多数动态网页中,绝大部分内容是静态的,只有少量内容需要动态实现。但是为了这少量的动态内容,程序猿依然要用Servlet 输出其中所有的静态内容,这就使得整个Servlet 程序代码非常臃肿,导致Servlet 的开发效率非常低下。

  为了弥补Servlet 的缺陷,SUN公司在Servlet 的基础上推出了JSP(Java Server Pages)技术作为解决方案。JSP是简化Servlet 编写的一种技术,它由静态部分和动态部分两部分组成,静态部分用于写入标准的HTML标签及内容;动态部分就是嵌入的Java代码与JSP动态标签了。通过这种方式,使静态的部分直接使用HTML代码编写,对于动态的内容则使用 JAVA 脚本编写。

  对于Servlet 来说,无论动态、静态都用Java代码编写;而JSP则将静态的分出来,全部用HTML写(底层还是使用Java包装);动态的用Java 写。究其本质还是一样的,所以说,JSP的本质就是一种特殊的Servlet 。

优点缺点
JSP在原有html的基础上添加java脚本,构成jsp页面
Servlet动态资源,可以编程。不适合设置html响应体,需要大量的response.getWriter().print(“”)
HTML静态页面,不能包含动态信息

JSP工作原理

JSP程序需要运行在特定的Web服务器上,如Tomcat等。JSP文件的执行流程:
1. 客户端发送请求到服务器端
2. 服务器做出响应(如果服务器端请求的是一个HTML页面,服务器将直接返回HTML页面)
3. JSP页面在第一次执行的时候会被服务器端的JSP引擎转换为Servlet程序(也就是Java源文件)
4. 调用Java编译器将Servlet程序编译为字节码文件(.class)文件,并由虚拟机解释执行

如果JSP文件在转换源文件的过程中发现错误,转换中断,并向服务器和客户端发出错误信息。如果转换成功,JSP引擎将把源文件编译成相应的字节码文件。然后创建一个Servlet实例,并执行 jsplnit() 方法,jsplnit() 方法在Servlet的生命周期中只被执行一次,此方法将被调用以处理客户端的请求,每一个请求对应一个线程,如果同时有多个客户端请求JSP文件,JSP引擎将会创建多个线程,每个客户端对应一个线程。JSP以多线程的方式执行大大降低了对系统的资源需求,提高了系统的并发量及响应速度。

Servlet始终驻于内存中,所以响应比较快,如果.jsp文件被修改,服务器将根据设置进行重新编译,重新编译的结果将取代内存中的Servlet,并继续上述处理过程,在第一次请求JSP的时候将会有一些延迟。

JSP是一种特殊的Servlet,JSP还是用Servlet方式实现的

Servlet工作原理

Servlet是用Java编写的服务器端程序,与协议和平台无关。Servlet可以动态扩展服务器端的处理能力,并采用请求响应模式提供Web服务。Servlet处理客户端请求结果如下:
1. 客户端发送请求到服务器端
2. 服务器将请求信息发送到Servlet
3. Servlet根据客户端的请求信息生成相应的响应内容,并将其传给服务器
4. 服务器将响应返回给客户端

Servlet容器: Servlet容器担当着服务器与Servlet之间的中间人的角色,Web服务器将请求的Servlet的URL和request对象转交给Servlet容器,由Servlet容器调用相应的Servlet程序处理相应的Servlet程序处理该请求,并将Servlet的请求结果发送给Web服务器。Tomcat是最常用的Servlet/Jsp容器

Servlet的生命周期:
1. ### 加载和实例化
容器负责加载和实例化一个Servlet对象,实例化和加载发生在引擎启动的时候,也可以推迟到容器需要该Servlet为客户请求服务的时候

  1. ### 初始化
    init()方法用于初始化操作,该方法在Servlet的生命周期中只执行一次,初始化的过程用来读取永久的配置信息,以及一些其他的只需要执行一次的任务
  2. ### 处理请求service()方法由Servlet容器调用,以允许Servlet响应一个请求。
  3. ### 移除实例
    调用destory()方法(也只调用一次),服务器决定删除已经加载的Servlet实例之间将调用Servlet的destory()方法

当Servlet容器接收到一个请求的时候,先会在容器池内查找被请求的Servlet实例是否已经存在,若不存在,则会加载和实例化被请求的Servlet,并对它进行初始化;若已存在,则直接调用Servlet的service()方法,然后根据HTTP请求的不同,在service()内部调用doGet()或doPost()等方法处理请求。当Servlet容器下一次接收到相同的请求的时候,只需创建一个ServletRequest对象和ServletResponse对象,并将他们作为参数传递给service()方法,同时建一个线程处理该请求,当不需要Servlet时,应调用destory()方法移除实例。

小知识:

  • response.sendRedirect() -重定向

    1. 页面跳转,地址栏改变
    2. 浏览器俩次请求
    3. 重定向之后当前页面所有数据信息在下一个页面全部失效
  • request.getRequestDispatcher() -请求转发

    1. 页面跳转,地址栏不变
    2. 浏览器一次请求
  • JSP的内建对象out、request、response、session、config、page、pageContext是线程安全的,而application在整个系统内被调用,是线程不安全的

Servlet的多线程机制

Servlet体系结构建立在Java多线程机制之上,生命周期由Web容器负责,当客户端第一次请求某个Servlet的时候,Servlet容器将会根据web.xml文件实例化这个Servlet类,当再有其他客户请求该Servlet的时候,一般不会再实例化该Servlet类,就会出现多个线程使用同一个Servlet实例的情况。线程多的情况下就会出现 数据不一致

编写线程安全的Servlet

  1. 实现SingleThreadModel接口
    此接口指定系统如何处理对同一个Servlet的调用,如果一个Servlet被这个接口指定,那么这个Servlet中的Service方法将不会由两个线程同时执行,就不会出现线程安全的问题

  2. 同步对共享数据的操作

    使用synchronized关键字能保证一次只有一个线程可以访问被保护的区段

  3. 避免使用成员变量(实例变量)

    在Servlet中尽量使用局部变量来保证线程安全
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值