java servlet

Java Servlet

动态网页是指在不同的时刻,和不同的情况下从服务器端返回的页面内容是不同的,变化的,它的解析执行是在服务器端完成的。

动态html是指依赖浏览器对页面脚本内容进行解析,生成不同的页面,但是从服务器端返回的内容是相同的,它的解析执行是在客户端进行。

动态网页内容的创建过程包含两个步骤:

首先使用某种编程语言编写出相应的动态网页程序;

 

然后由一个专门的WEB服务器程序模块来解析执行该动态网页程序。

在动态网页程序的代码中可以完成各种程序逻辑的控制,获取客户端传递的数据,对数据库进行操作,创建输出内容等功能,WEB程序开发就是指使用某种编程语言来编写完成上述功能的动态网页程序。

动态网页程序需要有一个专门的WEB服务器程序模块来解析执行,专门解析和执行某种动态网页程序的WEB服务器程序模块习惯上被称为引擎,譬如ASP引擎,Servlet引擎,JSP引擎。

只有引擎会与浏览器直接进行信息交换,动态网页程序不直接与浏览器进行信息交互,动态网页程序只与引擎进行信息交换,由引擎将浏览器的信息传递给动态网页程序和将动态网页策划那个徐生成的结果回送给浏览器。

引擎提供的API由两个基本的作用:一些API用于将文芳请求的相关信息传递给动态网页程序;另外一些API将动态网页程序产生的结果传递给引擎。

 


 

●客户端向WEB服务器请求●的URL资源路径,不仅可以指向服务器端的一个静态HTML文件,还可以指向服务器端的某种可被解析运行的程序文件。

●如果客户端请求的URL后缀名符合某种引擎所处理的资源名的特征,WEB服务器把请求转交给相应的引擎去处理,然后由引擎去调用某个程序文件,并将程序动态产生的内容返回给客户端。

Servlet技术简介:

Servlet技术是SUN公司提供的一种实现动态网页的解决方法,它是基于Java编程语言的WEB服务器端编程技术。

Servlet技术也是JSP技术(另外一种动态网页开发技术)的基础。

一个Servlet程序就是一个实现了特殊接口的Java类,它由支持Servelt(具有Servlet引擎)WEB服务器调用和启动运行,一个Servlet程序负责处理它所对应的一个或一组URL地址的访问请求,并接收客户端发出的访问请求信息和产生响应内容。

Servelet程序可以完成普通Java程序所能完成的大多数人物:

获取客户端通过HTMLFORM表单递交的数据和URL后面参数信息

创建客户端的响应消息内容

访问服务器端的文件系统。

调用其它Java类。

C/S系统架构的特点

缺点:

数据库系统支持的并发连接有限,限制了同时运行的客户端程序的数目。

业务逻辑处理和界面都有客户端程序负责处理,一旦逻辑或者显示界面要发生变化,则需要对整个客户端程序的修改,不利于软件的维护和功能扩展。

每个客户机上都需要客户端程序。

一个Servlet程序就是一个实现了javax.servlet.Servlet接口的Java类,Servlet接口定义了Servlet引擎和Servlet程序之间通信的协议约定。

javax.servlet.GenericServlet类实现了Servlet接口,她实现了Servlet程序的基本特正和功能。

javax.servlet.http.HttpServlet类是GenerciServlet的子类,它在GenericServlet类的基础上进行了一些针对HTTP特点的扩充。

客户端每次访问一个支持HTTPServlet程序时,Servlet引擎都将调用Servletservice方法进行处理。service方法接收两个参数。一个是用于封装HTTP请求消息的对象,其类型为HttpServletRequest,另一个是用于代表HTTP响应消息的对象,其类型为HttpServletResponse.

调用HttpServletResponse对象的getWriter方法可以获得一个文本输出流对象,向这个流对象中写入的数据将作为HTTP响应消息的实体内容部分发送给客户端。

 

 

 

 

 

Servlet的注册与运行

Servlet程序必须通过Servlet引擎启动运行,并且存储目录有特殊要求,通常需要存储在<WEB应用程序目录>/WEB-INF/classes/目录中。

Servlet程序必须在WEB应用程序的web.xml文件中进行注册和映射其访问路径,才可以被Servlet引擎加载和被外界访问。

一个<servlet>元素用于注册一个Servlet,它包含有两个主要的子元素:<servlet-name><servlet-class>,分别用于设置Servlet的注册名称和Servlet的完整类名。

一个<servlet-mapping>元素用于注册一个已注册的Servlet的一个对外访问路径,它包含有两个子元素:<servlet-name><url-pattern>,分别用于指定Servlet的注册名称和Servlet的访问路径。

<servlet>

<servlet-name>AnyName</servlet-name>

<servlet-class>HelloServlet</servlet-class>

</servlet>

…….

<servlet-mapping>

<servlet-name>AnyName</servlet-name>

<url-pattern>/demo/hello.do</url-pattern>

</servlet-mapping>

Servlet映射的细节:

同一个Servlet可以被映射到多个URL上,即多个<servlet-mapping>元素的<servlet-name>资源数据的设置值可以是同一个Servlet的注册名。

Servlet映射到的URL中也可以使用*通配符,但是只能有两种固定的格式 一种格式是*.扩展名,另一种格式是以正斜杠(/)开头并以”/*”结尾

特别提醒:1.映射URL不能设置为”/action/*.xx”;  2.Servlet程序不能被设置为Web应用程序的目录默认网页文档

 

Servlet映射的最具体匹配规则原则:

对于如下的一些映射关系:

   /abc/*   映射到   Servlet1

   /*       映射到   Servlet2

  /abc      映射到   Servlet3

  *.do      映射到   Servlet4(优先级最低)

将发生如下一些行为:

当请求URL “/abc/a.html”

Servlet引擎将调用Servlet1

当请求URL “/abc”时, “/abc/*””/abc”都可以匹配这个URL,

Servlet引擎将调用Servlet3.

当请求URL”/abc/a.do”时,”/abc/*””*.do”都可以匹配这个URL,

Servlet引擎将调用Servlet1.

当请求URL”/a.do”时,“/*”和”*.do”都可以匹配这个URL

Servlet引擎将调用Servlet2.

当请求URL”/xxx/yyy/a.do”时,”/*””*.do”都可以匹配这个URL,

Servlet引擎将调用Servlet2

 

Servlet激活器

Tomcatexample应用程序的web.xml文件中的设置

<servlet-mapping>

<servlet-name>invoker</servlet-name>

<url-pattern>/servlet/*</url-pattern>

config/web.xml文件中的设置

<servlet>

<servlet-name>invoker</servlet-name>

<servlet-class>

org.apache.catalina.servlets.InvokerServlet

</servlet-class>

<load-on-startup>2</load-on-startup>

</servlet>

</servlet-mapping>

 

缺省Servlet

如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet.

凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它们的访问请求都将交给缺省Servlet处理,也就是说,缺省Servlet用于处理所有其他Servlet都不处理的访问请求。

<tomcat的安装目录>/config/web.xml文件中,注册了一个名称为org.apache.catalina,servlets.DefaultServletServlet,并将这个Servlet设置为了缺省Servlet.

当访问Tomcat服务器中的某个静态HTML文件和图片时,实际上是在访问这个缺省Servlet.

 

类装载器

Java虚拟机使用每一个类的第一件事情就是将该类的字节码装载进来,装载类字节码的功能是由类装载器完成的,类装载器负责根据一个类的名称来定位和生成类的字节码数据后返回给Java虚拟机。

类装载器本身也是一个Java类,Java虚拟机也允许开发人员编写自己的类装载器,以便通过其它各种特殊方法来产生类字节码。

不管类装载器采用什么方式,只要能够在内存中制造出给Java虚拟器调用类字节码即可。所以,把类装载器描述为类字节码的制造器更容易让人理解。

当一个类被加载后,Java虚拟机将其编译为可执行代码存储在内存中,并将索引信息存储进一个HashTable中,其索引关键字为与之相对应的类名。

Java程序中的类本身也是一种事务,它也可以用一个Java类来描述,这个特殊的类名就叫Class。类装载器转载某个类的字节码的过程实际上就是在创建Class类的一个实例对象,这个Class类的实例对象封装的内容正好是当前加载的类的字节码数据。

要想在程序中获得代表某个类的字节码数据的Class实例对象,可以采用下面的三种方式:

类名.class, 例如, System.class

对象.getClass, 例如, new Date.getClass()

Class.forName(“类名”)

Java类库中提供了一个java.lang.ClassLoader来作为类装载器的基类,Java虚拟机和程序都调用ClassLoader类的loadClass方法来加载类,ClassLoader是一个抽象类,真正的类装载器必须是ClassLoader的子类。

类装载器的基本策略:

一个类装载器本身也是一个Java类,所以,类装载器自身也需要被另外的一个类装载器装载。

Java虚拟机中内嵌了一个称为Bootstrap的类装载器,它属于Java虚拟器的内核,不用类装载器装载,Bootstrap类装载器负责加载Java核心包中的类(rt.jar文件中的类),这些类的Class.getClassLoader方法返回值为null,即表示是Bootstrap类装载器。

ExtClassLoader类装载器负责加载存放在<JAVA_HOME>/jre/lib/ext目录下的jar包中的类,AppClassLoader负责加载应用程序的启动执行。

类装载器的委托模式:

一个Java虚拟机中的所有类装载器采用具有父子关系的树形结构进行组织,在实例化每个类装载器对象时,需要为其指定一个父级类装载器对象,如果没有指定的话,则以ClassLoader.getSystemClassLoader()方法返回的系统类装载器作为其父级类装载器对象。

系统类装载器通常被设置为启动应用程序的AppClassLoader,可以通过java.system.class.loader系统属性来将系统类装载器设置为其它类装载器。ExtClassLoaderAppClassLoader父级类装载器,ExtClassLoader没有父级类装载器。

每个ClassLoader本身只能分别加载特定位置和目录中的类,但是,ClassLoader被设计成了一种委托模式,使得某一个ClassLoader可以委托它的父级类装载器去加载类,从而让应用程序可以借助某一个子级的ClassLoader去多个位置和目录中进行类的加载。

当要加载一个类时,ClassLoaderloadClass方法首先查找这个类是否已经被加载,如果没有加载,则委托其父级类装载器去加载这个类,如果父级诶装载器无法加载这个类,子级类装载器才调用自己内部的finadClass方法去进行真正的加载,委托过程会一直追溯到BootStrap类装载器,如果委托过程中的所有类装载器都不能完成类的装载,最终就会 ClassNotFoundException异常。

一个类装载器只能创建某个类的一份字节码数据,即只能为某个类创建一个与之对应的Class实例对象,在一个Java虚拟机中可以存在多个类加载器,每个类加载器都拥有自己的名次空间,对于同一类,每个类加载器都可以创建它的一个Class实例对象。

线程中的类加载器,

如果在类A中使用new关键字创建类B,Java虚拟机将使用加载类A的类加载器来加载类B,如果在一个类中调用Class.forName方法来动态加载另外一个类,可以通过传递个Class.forName方法的一个参数来指定另外那个类的类加载器,如果没有指定该参数,则使用加载当前类的类加载器。

依据一个的存放位置,这个类最终只能由一个特定的类装载器装载。对于一个已被父级类装载器装载的类来说,Java虚拟机默认也使用这个类装载器去装载它所调用的其他类,由于父级类装载器不会委托子级来装载器去装载类,所以,在一般情况下,一个已被父类装载器装载的类无法调用那些只能被子级类装载器发现和装载的其他类。

每个运行中的线程都有一个关联的上下文类装载器,可以使用Thread.setContextClassLoader()方法设置线程的上下文类装载器。

每个线程默认的上下位类装载器是其父线程的上下文类装载器,而主线程的类装载器初始设置为ClassLoader.getSystemClassLoader()方法返回的系统类加载器。

当线程中运行的代码需要使用某个类时,它使用上下文类装载器来装载这个类,上下文类装载器首先会委托它的父级类装载器装载这个类,如果父级的装载器无法装载时,上下文类装载器才自己进行装载。

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值