容器使用taglib伪指令定位标签库描述器并将其和基于标签前缀页面中用到的定制标签相匹配。那么容器读取database.tld文件取得其描述的标签列表和与每一标签相关的标签处理器类的名字。
JSP页面存在3种形式:1、.jsp文件,页面作者编写的最初的源文件,它可能包含HTML、scriptlet、表达式、声明、行为标记和伪指令。2、.java文件,与.jsp文件等价servlet的java源码。此servlet由JSP容器生成。3、.class文件,生成的Java servlet的已编译形式。当一个HTTP客户端向JSP页面发出请求时,JSP容器检查.jsp和.java文件的修改日期。如果.java文件并不存在或比.jsp文件旧(如果JSP页面已被修改时发生),JSP容器重新创建java servlet并编译它。
网站建设前端知识--JSP容器的功能
标签处理器的功能
标签组件包含:1、具有0或多个属性的开始标记<app:mail…>。2、结束标记</app:mail>。3、开始和结束标记之间的行,称为标签体,包含一般文本或其他JSP语句。在将标签转换成servlet代码时,容器对每一组件调用标签处理器,使用pageContext对象共享处理器属性。这些方法的过程有时称为处理器的生命期。在此工作中,处理器必须实现下面两个接口中的一个:1、javax.servlet.jsp.tagext.Tag对于不在其体上进行操作的标签。2、javax.servlet.jsp.tagext.BodyTag是Tag子接口的标签。这些接口指定了标签处理器必须提供的生命期方法。
网站建设之JSP会话跟踪
因为web服务器在请求之间不会记住客户端,因此保持一个会话的唯一方式是客户端跟踪会话,实现此功能有两种基本方式:1、客户端记住所有会话的相关数据并在必要时将之发回到服务器。2、服务器保持所有数据,对其设置一个标识,让客户端记住该标识。
第一种方案实现比较简单,不需要服务器部分加入特殊功能。此方案需要来回传送大量的数据,可能会降低性能。另一问题是服务器端对象,如数据库和网络连接对每一请求必须被重新初始化。为此,此方案最合适于小批量数据的长期持久性发送。如用户优先权和帐号。第二种方案功能更多,一旦服务器初始化了一个会话且客户端接受了它,服务器就可以构建复杂的,有效的对象并保存大量的数据,但只需一个关键字就可以区分会话。
JSP中隐藏域
HTML窗体支持HIDDEN类型的输入元素。隐藏域与HTTP请求中其他窗体参数一起被发送到web服务器,但它们没有任何可视表示。它们只用于包含一个请求的字母或常量值。类似技术也用于CICS和主框架事务处理监视器提供事务处理代码。理论上,隐藏域可用于一般HTML web页面,但如果要进行会话跟踪,它们就必须由类似CGI、servlet或JSP服务器进程创建的动态生成的web页面。
隐藏域非常适合不需大量数据存储或对象初始化的来回的会话式应用。一个典型实例是Tomcat实例文件夹中包含的猜数游戏。此游戏选择1到100之间的一个随机整数,然后让用户猜它。每一猜测后,游戏告诉用户每一次猜测值是否太小、太大或刚刚好。在此实例中JSP页面使用一个名为state的隐藏域来跟踪游戏中发生的事件。
JSP中创建会话
Servlet通过调用HttpServletRequest中的getSession或getSession(Boolean create)方法指出它要使用的会话。不带参数的getSession方法是调用getSession(true)的一种简便写法。Create参数指出如果会话不存在,servlet引擎是否应该创建一个新的会话。如果参数是false,则servlet只能对存在的会话实施操作。每种情况下,都要检验请求,查看它是否包含一个有效的会话ID,如果是,servlet容器返回会话对象的引用,让后用它来存储和检索会话属性。
网站建设之JSP中线程管理
Servlet和JSP页面比原来的服务器端技术有很大的优势。因为它们被载入内存,在多线程环境下作为单一实例运行。此方式还可以权衡。然而,多线程模型引入了简单模型不存在困难性。一个线程是具有自己的栈和程序计数的控制的单顺序流。使用多线程的程序表现为同时做多件事情。在同一进程中的同一时间,一个线程可以独立于其他线程进行操作,并共享所有的进程对象。
Web服务器本身就是可用线程的例子。一个简单的web服务器操作如下:1、创建一个serverSocket,调用其accept()方法等待HTTP客户端请求。2、取得accept()方法返回的客户端Socket对象,启动一个单独的线程处理其请求。3、返回到步骤1,在上一请求正被其他线程处理的同时接受更多的请求。通常Java(不只是在JSP页面中)创建和使用多线程很容易。语言和类库理论上都是构建在带有线程的基础上。Java.lang.Object,所有对象的最终基类,具有同步线程操作的方法,被每一个Java对象所继承。
会话捆绑侦听者
会话API提供跟踪对象何时被加入和删除的方式。要收到这些事件通知的对象可以实现HttpSessionBindingListener接口。实现类必须提供两个方法,在两个方法中,均收到一个HttpSessionBindingEvent的实例。事件参数具有检索会话和判断对象捆绑到会话的名字的方法。通过会话捆绑侦听者得到的主要优点是它们可以释放其获得的资源。而不管客户端显式关闭应用或会话超时。这使得此接口对管理数据库连接非常有用。JDBC提供连接池,但许多驱动器还没有实现它。这样的话,一种替换方式是使用一个知道使自己断连的会话驻留的连接。
多线程的应用
一些多线程特别有用的存在于服务器端环境。其中一个是自动开始的后台进程,并不捆绑到任何特定请求,类似于一个Unix例程或一个Windows 服务。这可以在servlet环境中使用下列技术实现:1、init方法启动一个线程执行所需任务。包括打开一个套接字服务于请求或周期性地读取具有动态修改数据的web页面。2、对命令,管理任务和状态报告严格使用doget方法。通常需要给出可以关闭或重启后台线程的命令。3、在destroy方法中,释放任意使用的资源后关闭线程。
Servlet(JSP)可设计为发布描述器中的load-on-startup,因此servlet引擎一运行它就开始运行,而无需注册用户。因为servlet引擎本身典型情况可作为一个例程或服务运行,因此可以将这样的进程写为Java servlet。多线程另一点有益的用法是处理长时间运行的请求,如复杂的数据分析或其他类似工程的请求。如果一个客户端请求一个事件负载相当重的服务器进程,则客户端和servlet引擎都将等待直到其完成,当然也还有其他情况存在。
基类的初始化
现在要创建派生类对象已经不是一个类的事情了,它会牵涉到两个类——基类和派生类,因此要搞清楚它究竟是怎么创建的,就优点难度了。从局外人的角度来看,新类具备了和旧类完全相同的接口,并且还有可能会有一些它自己的方法和数据。但继承并不仅仅是拷贝基类的接口。当你创建一个派生类对象的时候,这个对象里面还有一个基类的子对象。这个子对象同基类自己创建的对象没什么两样。这是从外面看来,这个子对象被包裹在派生类的对象里面。
当然,基类子对象的正确初始化也是非常重要的,而且只有一个办法能保证这一点:调用基类的构造函数来进行初始化,因为只有它才掌握怎样才能正确地进行初始化的信息和权限。Java会让派生类的构造函数自动地调用基类的构造函数。构造行为是从基类向外发展的,所以基类会在派生类的构造函数访问它之前先进行初始化。即便你不创建cartoon()的构造函数,编译器也会为你造一个默认的构造函数,然后再由它去调用基类的构造函数。
继承所使用的语法
继承是Java(也是所有OOP语言)不可分割的一部分。实际上当你创建类的时候,你就是在继承,要么是显式地继承别的什么类,要么是隐含地继承了标准Java根类:Object。合成的语法很平淡,但继承就有所不同了。继承的时候,你得先声明“新类和旧类是一样的”。跟平常一样,你得先在程序里写上类的名字,但是在开始定义类之前,你还得加上extends关键词和基类的名字。做完这些之后,新类就会自动获得基类的全部成员和方法。
你可以为每个类都创建一个main(),而且这也是一种值得提倡的编程方法,因为这样一来,测试代码就能都放进类里了。即使程序包括了很多类,它也只会调用你在命令行下给出的那个类的main()方法。于是,当你输入Java detergent的时候,它就会调用detergent.main()。虽然cleanser不是public的,但是你也可以用Java cleanser来调用cleanser.main()。这种往每个类里都放一个main()的做法,能让类的单元测试变得更容易一些。做完测试以后,你也不必移除main(),留下它可以供以后的测试用。