servlet是运行在web容器中(在现在的web应用中,web容器一般指Tomcat)的,并不是独立的与web服务器交互,用户的请求响应都是在web容器中创建的。而在开发过程中,一个项目涉及到的servlet是很多的,那么容器如何找到适当的servlet呢?这里涉及到servlet的一个知识点,就是servlet的名字。
servlet有三个名字,一个是客户知道的URL名(我要点击指向”resgister/resgisterMe”servlet的链接),一个是部署人员知道的秘密的部署名(我要把这个servlet叫做”EnrollServlet”),最后一个是实际的文件名(classes-registration-SignUpServlet.class)。客户知道的URL名,实际上就是HTML中对应的一个servlet名字,但是用户并不知道servlet在项目中的具体位置,也就是说,公共URL,只是一个虚构的名字,完全是为用户提供的。其次,在部署项目的时候,部署人员可以虚拟一个名字,这个名字不需要跟servlet所在的类路径相同,也不需要同公共URL一样,只是用于部署servlet。而在开发中,servlet类有一个完全限定名,其中包含类名和包名,servlet类文件有一个实际的路径和文件名,这取决于服务器上包目录结构所在的具体位置 。
通常在开发web程序的时候,会有相关的部署文件,那么对于部署文件,以上三个名字分别是指什么?
<servlet>
<servlet-name>Internal name 1</servlet-name>
<servlet-class>foo.Servlet1</servet-class>
</servlet>
<servlet-mapping>
<servlet-name>Internal name 1</servlet-name>
<url-pattern>/Public</url-pattern>
</servlet-mapping>
上面的代码中,servlet元素告诉容器哪些类文件属于一个特定的web应用,servlet-name元素用于把一个servlet元素绑定到一个特定的servlet-mapping元素,最终这个用户看不到这个名,这个名只在部署描述文件的其他部分使用,servlet-class放置类的完全限定名(但是不要加上“.class”扩展名)。而对于上面的servlet-mapping元素,在请求到来时,容器会在运行时使用这个元素询问“对于请求的URL,我应该调用哪个servlet?”,因此可以知道,在url-pattern中,是提供给用户的虚拟的servlet名字,并不是具体的类名。