jsp

TODO 想将Jsp的重点一次指明。

JSP的运行机制

JSP的运行机制:

1、首先,客户端发送URL请求。Tomcat服务器获取URL请求,如果获取的后缀名是.jsp,则Tomcat把请求交给JSPServlet处理

2、如果JSP第一次被调用,将把JSP编译成Servlet,如果JSP不被修改将不会再被编译,否则将会再次编译。通常,在JSP文件没有被修改的前提下,JSP只会被编译一次,所以在第一次访问的时候访问的速度会比较慢

3、编译的过程如下:Tomcat调用service方法编译JSP文件,创建一个*_jsp.java文件保存到服务器的\work\Catalina\目录下的相对应的项目文件夹里面,该java文件继承自父类HttpJspBase类

4、创建HttpServletRequest和HttpServletResponse

5、调用*_jsp.java继承自父类HttpJspBase的方法service(request,response)

6、在service方法里面会调用_jspService(request,response)方法渲染输出html返回给客户端


本文链接: http://www.itzhai.com/jsp-mechanism-and-principle-of-operation.html

jsp多线程

对每一个请求,web容器创建一个新的线程来处理该请求。如果有多个客户端同时请求该JSP文件,则JSP引擎会创建多个线程。每个客户端请求,对应一个线程。但servlet实例只有一个。

以多线程方式执行可大大降低对系统的资源需求,提高系统的并发量及响应时间.

但应该注意多线程的编程限制,由于该servlet始终驻于内存,所以响应是非常快的。如果.jsp文件被修改了,服务器将根据设置决定是否对该文件重新编译,如果需要重新编译,则将编译结果取代内存中的servlet(内存中的servlet需要Destroy()吗??),并继续上述处理过程(某些web应用服务器是这样的。但,Tomcat中如果.jsp文件被修改了,必须重启Tomcat才能有效。是这样吧??)。

如果在任何时候如果由于系统资源不足的原因,web容器将以某种不确定的方式将servlet从内存中移去。当这种情况发生时jspDestroy()方法首先被调用, 然后servlet实例便被标记加入"垃圾收集"处理。


如果JSP第一次被调用,将把JSP编译成Servlet(也可以事先编译好。是这样吧??),且一般只编译这一次,初始化放入内存中。

jsp_servlet的Destroy()方法,一般只有服务器停止时执行(是这样吧??)


jsp本质就是servlet(单实例,多线程),采用的请求/响应模式。

浏览器输入URL可以访问jsp,同理,也可以访问servlet(*.java的*.class的位置)


jsp的指令元素

<%@page %>定义JSP文件的全局属性

<%@include %>在JSP被转为Serlet(*.java)文件时,静态包含一个文件的内容。在JSP转译前起作用。


jsp脚本元素

1、表达式

<%=expression%>  等价于<%  out.print(String.valueof(expression)); %>,位于JSP被转为Serlet(*.java)文件的void _jspService()方法中,局部变量。

2、声明

<%! 声明;>,位于JSP被转为Serlet(*.java)文件的类成员声明(定义)中。根据servlet(单实例,多线程)的特点,可知,这是被所有客户端共享的。


jsp动作元素

<jsp:param>为其他标签提供附加信息,完成在页面间传递参数。必须配合<jsp:include>、<jsp:forward>、<jsp:plugin>使用。

<jsp:include>在当前的JSP页面中,包含静态或动态资源。在处理用户请求时起作用。

<jsp:forward>把当前的JSP页面从定向到另一个页面(HTML、JSP或servlet),但是地址不变(浏览器的URL),内容则是另一个页面的内容。

转发工作,是在服务器端进行的,不会引起用户端的二次请求,因此效率比重定向高。

<jsp:setProperty>设置已经实例化的Bean对象属性。只有在新建Bean实例时才会执行,如果是使用现有实例(已经设置过属性的实例?)则不执行。

<jsp:getProperty>用来提取一个Bean属性值。访问的属性值将它转化成一个String发送到输出流中。

<jsp:useBean>用来装载一个将在JSP页面中使用的javaBean。----实现view页面与业务逻辑分离的核心。scope参数:page/request/session/application。

javaBean也是一个java类,成员变量都设置了set()和get()方法----对应<jsp:setProperty>、<jsp:getProperty>。

<jsp:plugin>元素用于在浏览器中播放或显示一个对象(典型的就是applet和Bean),而这种显示需要在浏览器的java插件。

当Jsp文件被编译,送往浏览器时,<jsp:plugin>元素将会根据浏览器的版本替换成<object>或者<embed>元素。
注意,<object>用于HTML 4.0 ,<embed>用于HTML 3.2。


jsp 内置对象

Request(Javax.servlet.ServletRequest)它包含了有关浏览器请求的信息.通过该对象可以获得请求中的头信息、Cookie和请求参数。

对应一次请求,作用域是当前页面。从当前页面利用它获取需要的客户端请求信息。

<form  action="abc.jsp">:form向abc.jsp提取请求req,则只能从abc.jsp页面获取请求req,而不是<form>所在的页面(它是提交请求,请求不属于他,而应属于接收者)。

Response(Javax.servlet.ServletResponse)作为JSP页面处理结果返回给用户的响应存储在该对象中。并提供了设置响应内容、响应头以及重定向的方法(如cookies,头信息等)

对应一次请求的响应,作用域是当前页面。

Out(Javax.servlet.jsp.JspWriter)用于将内容写入JSP页面实例的输出流中,提供了几个方法使你能用于向浏览器回送输出结果。

对应一次请求的响应,作用域是当前页面。

pageContext(Javax.servlet.jsp.PageContext)描述了当前JSP页面的运行环境。可以返回JSP页面的其他隐式对象及其属性的访问,另外,它还实现将控制权从当前页面传输至其他页面的方法(控制权??)。

对应当前JSP页面。

Session(javax.servlet.http.HttpSession)会话对象存储有关此会话的信息,也可以将属性赋给一个会话,每个属性都有名称和值。会话对象主要用于存储和检索属性值。

对应一次会话,可用于多个页面。

一般情况下,用户首次登录系统时,容器会给此用户分配一个唯一的标记的SessionID。这个ID用于区别于其他用户。当用户退出登录系统时,这个session就会自动消失。session->HttpSession.

每个用户独有一个SessionID, session对象信息保存在容器里,但session对象的ID保存在客户端的Cookie中。

Application(javax.servle.ServletContext)存储了运行JSP页面的servlet以及在同一应用程序中的任何Web组件的上下文信息。

服务器启动后,就产生了这1个application对象,用户所访问的网站的各个页面之间浏览时,这个application对象都是同一个,直到服务器关闭。该对象能够被所有用户在不同的页面中共享(单实例,多线程??)。

注意区分:servlet,本质是某个页面,单实例,多线程。

Page(Java.lang.Object)表示当前JSP页面的servlet实例

对应当前JSP页面。

Config(javax.servlet.ServletConfig)该对象用于存取servlet实例的初始化参数。

对应当前页面(servlet、jsp)。

Exception ( Javax.lang.Throwable )在某个页面抛出异常时,将转发至JSP错误页面,提供此对象是为了在JSP中处理错误。只有在错误页面中才可使用 <%@page isErrorPage=true%>


http://hi.baidu.com/may_62/item/02bbebc01d9da82747d5c02a

http://www.cnblogs.com/kelin1314/archive/2011/03/03/1969578.html

jsp转成的servlet中,使用out.wrte()向

浏览器中输出。out的内容会被先缓存在response中,最后再一次性给浏览器。对于print和write。除了字符集以外。这两个是没有多大区别的,因为JspWriter继承了Writer类,而这个类就实现了这两个方法。所以这两个方法你不用管它。print默认使用本身字符集。


jsp的pageContext对象

pageContext对象能够存取其他隐含对象。

    JSP转成的servlet中就是用PageContext对象取得其他隐含对象的。

例如

1、类成员:private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

2、_jspService()方法中

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;

      pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();//其它页面调用该方法产生的application对象是同一个。
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;



Jsp的session对象

session对象一般存储那些非request的信息,用于多个页面传递,如登录的用户名、密码。当然,你也可以将request的信息放于session对象,但是,一般不需要(对吧??)。

为什么session对象的作用域是一次会话(多个页面)?

因为客户端第一次访问某网站(web服务器)时,服务器给该客户端一个session对象和唯一的session ID,并将session对象放于服务器内,比如某个散列表中。以后该客户端访问这个服务器的同时,就会传回session ID(方法包括URL重写,发送cookie和表单隐藏字段(很少用))。服务器根据该session ID取出散列表中的session对象给被访问的位置(jsp页面、servlet)。

客户端是如何知道发送哪个session ID的呢?

客户端访问某个服务器需要发送session ID,会检查所有存储的session ID,如果某个session ID所声明的作用范围大于等于将要请求的资源所在的位置,则把该session ID发送给服务器。

http://java.chinaitlab.com/server/361839.html(session和cookie机制)

使用举例:

登录校验:

方案1
可以定义一个页面A,在页面里面判断Session["user"]是不是空,如果是跳转到登录页面
其他页面(除了登录页面外)都继承A页面。
在登录页面登录成功后把当前用户名存入Session["user"]
方案2
在web.config里面设置登录页面,及不允许匿名访问,则未登录用户会自动跳转到登录页面

---页面的跳转,session也跟着传递。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值