1. Servlet的标注信息:
1) 在Servlet3.0中提供了标注功能,以告知Web容器Servlet会提供哪些服务及一些额外的信息;
2) 标注采用Java的标注语法@打头,完整的标注为@WebServlet(...),后面不需要加分号;
3) 可标注的内容:单参数默认指定URL模式,例如@WebServlet("/hello.view"),下面介绍多参数的语法
!!以下所有参数都具有默认值,这里只介绍三个最常用的参数
i. name:为Servlet注册一个别名给Web容器,默认值是Servlet的完整包路径名,由于包路径名过长可以去一个方便项目管理的简短的名字,并且要见名知意;
ii. urlPatterns:URL模式
iii. loadOnStartup:启动参数,Servlet的启动过程分为三步,启动(即Run)-> 实例化 -> 初始化 -> 开始服务,而通常在默认值(0)情况下,Servlet启动后并不会立即实例化,而是等待客户端第一次请求它时才会实例化并初始化,这就意味着第一次请求会花费很多额外的时间,如果希望启动Servlet并立马完成初始化就要为该参数赋予一个大于0的值,而数字的大小则表示优先级,数字越小优先级越高,即越早启动,如果优先级相同,则具体的顺序时Web容器厂商的具体算法决定;
iv. 标注的例子,注意语法:
@WebServlet( name="Hello" // 不用花括号 urlPatterns={"/hello.view"} // 一定要加一个花括号 loadOnStartup=1 )
1) 上面的Servlet标注只适用于单个Servlet的自我标注,但是如果工程中有大量的Servlet需要统一部署则采用单个自我描述的方式可能不方便管理,想要查看整个部署情况不能用一个俯视的视角全局查看,我们很像将所有的Servlet的部署信息都写在一个文件里面,这个文件就是web.xml,叫做DD,即Deployment Descriptor,即部署描述文件;
2) 该文件必须放在工程目录的WebContent/WEB-INF目录下,可以在Eclipse中右击该节点New一个文件,取名为web.xml(注意!必须是这个名字);
3) 先来看一下该文件中几个最重要的标签:
i. <Servlet>:在该标签中向Web容器注册Servlet的别名,并指定该Servlet的完整包路径,将.class文件代表的类和别名关联起来,以及该Servlet的启动参数,例如:
<servlet> <servlet-name>Hello</servlet-name> <servlet-class>com.lirx.HelloServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>!!如果有多个Servlet就写多个Servlet标签,为每一个Servlet写一个;
!!注意,多个单词用连字符-分隔!
ii. <servlet-mapping>:将URL模式映射到用<servlet>这注册过的Servlet上,首先需要指定目标Servlet的注册别名,然后再指定其URL模式,例如:
<serlvet-mapping> <servlet-name>Hello</servlet-name> <url-pattern>/hello.view</urlpattern> </servlet-mapping>!!当Web容器得到请求参数/hello.view时会先找到servlet-mapping中该模式对应的servlet注册名Hello,然后再拿着这个注册名到各个servlet标签中找有没有该注册名的Servlet,找到后在读取它的包路径com.lirx.HelloServlet正确地启动服务;
!!所以!!servlet标签一定要定义在servlet-mapping标签之前,以为servlet中的servlet-name要给servlet-mapping用!
!!如果有多个请求同时到来,并且对应的Servlet的启动参数(即优先级)相同,那么就按照web.xml中servlet标签的书写顺序来启动!!
!!!web.xml中的其它信息:
a. 文件第一句是XML的处理命令,一般交代一下使用的XML的版本和编码:<?xml version="1.0" encoding="UTF-8"?>
b. 其次就是web-app标签,里面需要交代Web App的版本,这里指的就是Servlet的版本,我们使用的是3.0,其次就是指定本XML中使用到的标签的命名空间;
!XML中的标签基本都是自定义的,不同厂商定义的标签可能会相同,因此需要设置命名空间以区分那些相同的标签;
!!这里的命名空间采用官方定义的版本,所以都是固定的,写其他XML的时候只要复制黏贴即可;
!!servlet和servlet-mapping标签就包含在web-app标签中;
c. 举例:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" > <serlvet>... ... </web-app>
!就按照这个模板写即可;
3. 标注和DD之前的冲突:
1) 在Tomcat6.X版本中可以同时使用标注和DD两种方式对Servlet进行部署,只不过DD会覆盖掉标注中的值(即DD级别更高),因此在6.X中都是用标注作为默认值而DD作为实际值;
2) 但是在Tomcat8.X中标注和DD是冲突的,两者只能保留其一,否则Tomcat无法启动,可能是总结了前几个版本的经验,默认值和实际值仍会造成很多人为错误的地方,因此以后还是严格地将两者分开;
3) 使用标注还是DD?在工程规模较小的情况下标注可能更加便捷,但是在工程规模非常大的情况下还是使用DD统一部署为好!
4. 环境根目录:
1) URL中域名后面的根路径/并不是指你服务器文件系统的根路径,而是指Web应用程序的根路径,通常是定义为工程目录;
2) 可以在Eclipse中更改应用的环境根目录,在工程节点上右击Properties,然后选择Web Project Settings选项卡设置Context root即可;
5. Java EE标准下Web应用在Web容器中的基本部署:
!!这只是规范的一部分(基础部分),还有一部分(进阶内容)在后面一张中讲述!!
1) 首先在一个Web应用自己的目录下应该按照EE的标准这样部署:
i. 根目录是应用程序的目录,比如FirstSerlvet目录,这就是应用程序的环境目录,简称环境目录;
ii. WEB-INF是根目录下的最重要的子目录(还有一个是META-INF目录,这里还用不到,可以不定义),里面有三样东西:
a. web.xml部署描述文件;
b. lib目录:里面只能存放运行时jar库,只能放jar文件,一般用来放各种import导入的类库jar包;
c. classes目录:里面是用户自己编写的类,必须以包路径结构存放,入classes/com/lirx/HelloServlet.class;
!!WEB-INF中的内容对外界是全封闭的,客户端无法使用HTTP的任何方式获取其中的资源,除非通过Servlet/JSP的请求转发技术实现,但通常WEB-INF里都是应用程序的组件,这涉及到整个应用程序的安全问题,一般都不让外界访问,除了管理员自己的特殊需求外;
iii. 在环境目录下除了WEB-INF目录外还可以防止其它用途的目录,比如可以存放静态页面、图片、视频等,这些目录可以自定义,但是上面的WEB-INF以及其中web.xml、lib、classes都是不能改变名称的,这都是Java EE规定好的;
2) 但是Eclipse的工程目录并不是这样的!这是因为Eclipse这是一个IDE平台,是专门给程序员用以开发调试的,它的目录结构是为了方便管理源码、方便调试的,看一下他的目录结构:
i. 根目录下的.settings目录、.classpath文件、.project文件都是Eclipse的工程配置文件,里面定义了Eclipse该如何打开该工程的相关信息;
ii. 源码保存在src目录中,以包路径的形式保存;
iii. 源码编译好的类文件放在build目录中,也是以相应的包路径的形式保存;
iv. 还有一个WebContent目录,里面有两个子目录,一个是META-INF,还有一个是WEB-INF(但是里面都是空的);
3) 工程准备完毕之后进行部署:
i. Eclipse的WebContent才是真正的部署目录,等你的工程全部都准备好了,就应该在WEB-INF中创建lib、classes目录,以及web.xml文件;
ii. 然后将build中的类复制到classes目录下,然后将jar库复制到lib目录下,并编写web.xml;
iii. 最后将其它资源也按照Java EE的标准放到WebContent目录下,这样完整的Web应用程序就设置完成了;
iv. 将整个应用(打包后)放到Tomcat上完成部署:
a. 可以直接将WebContent整个目录复制到Tomcat根目录的webapps目录下完成部署(注意,复制过去后需要将WebContent改名为应用程序的名称,比如FirstServlet等);
b. 但推荐的方法不是直接复制整个目录,而是使用jar命令打包后再放到Tomcat的webapps目录下:在WebContent下使用命令jar cf ../ProjectName.war *,即可在WebContent外打出一个war包,war即Web Jar文件的缩写,然后再将war包放到Tomcat的webapps下即可;
!!一定要使用jar cf ../ProjectName.war *命令,不能在WebContent外使用jar cf ProjectName.war WebContent,因为后者是将WebContent这个文件夹打包,而前者是将WebCotent中的内容打包,后者比前者多了一个WebContent目录层级,Java EE规定下war包就是应用程序的根目录,里面直接就有WEB-INF,如果按照后者的方式打包,则war包下直接是WebContent目录而不是我们想要的WEB-INF、META-INF目录!!
v. 将应用部署到Tomcat上后,直接运行Tomcat的bin/startup.exe就能启动服务器,并且Tomcat会自动解析war包或者应用程序的目录来载入应用程序;