我使用的开发环境:
Eclipse java EE 2019-06
JDK1.8 JRE1.8 Tomcat 8.0
@WebServlet简介
@WebServlet标注允许servlet映射声明在servlet代码,作用同通过映射部署描述符(web.xml)文件的servlet.
@WebServlet解释
假如我起一个名为TesrServlet01的Servlet类,那么初始化的java代码中类顶部的@WebServlet标注声明如下所示。
如果在创建Dynamic Web Object文件时创建了web.xml会产生一个默认的内容,如下所示。
这个时候我们发现,web.xml中并没有自动产生TestServlet01的虚拟映射路径,这和《Java Web程序设计任务教程》中提供的流程出现了出入(该书中使用的Tomcat为7.0版,Servlet可能低于3.0)个人猜测是因为tomcat版本问题。
如果确定使用的是Tomcat 7或更新版本,则web.xml必须声明webapp 符合Servlet 3.0规范,以便让Tomcat扫描并处理注释。否则Tomcat仍将以与Servlet版本匹配的后备模式运行web.xml。Servlet API注释的支持仅在Servlet 3.0(Tomcat 7)中添加。
所以Servlet的配置是直接在生成的java代码中进行自动注解配置了,并映射文件,不再在web.xml中进行更新。这也就是为什么在创建文件的时候不是默认的产生web.xml文件,而是可以让你根据需要自己选择是否创建。(web.xml被@WebServlet代替)
@WebServlet属性
提供给@WebServlet标注使用的属性有valur属型,这个属性值为servlet提供URL映射,你可以显示使用下面的方式:
@WebServlet("/TestServlet01")
当你需要显式使用这个参数的时候通常是你要添加其他属性值给@WebServlet标注,以此可以给servlet提供几个不同的路径的映射,需要使用到urlPatterns属性,urlPatterns属性可以指定一个URL模式字符串数组映射servlet。如下:
@WebServlet(urlPatterns={"/TestServlet01","/Test02,"/Hello"})
注:value和urlPatterns任意其中一个是使用@WebServlet标注必要属性,并且不能同时被使用,否则会抛出异常。
另一个可以提供给@WebServlet标注使用的属性是name属性,name属性是可选用的。默认地,@WebServlet会将servlet声明为合法的类全名。在上面的例子中,name属性值即是com.test.z.HelloWorld。如果希望重写默认名,可提供name属性值给@WebServlet标注。如下:
@WebServlet(name="TTT",urlPatterns={"/TestServlet01","/Test02,"/Hello"})
默认名被重写,现在叫TTT
web.xml重写@WebServlet
当在java代码使用@WebServlet映射servlet时,部署描述符文件(web.xml)也可以一起使用来映射servlet。事实上有许多要求在应用程序中使用web.xml。比如提供一个欢迎页列表,定义错误页,过滤器,这些只能在web.xml中完成。
当使用web.xml文件定义和映射servlet时,一般情况下就不用@WebServlet标注。然而,如果你代码中仍使用@WebServlet标注,当遇上web.xml与@WebServlet标注同名的servlet,由web.xml提供的映射会重写由@WebServlet标注定义的映射。刚才提到过servlet会默认使用类全名,如果@WebServlet标注没有提供另一个name属性。
下面举一些例子:
此时
java代码中:
@WebServlet("/TestServlet01")
web.xml文件中:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>chapter03</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Different</servlet-name>
<servlet-class>
cn.itcast.servlet.TestServlet01
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Different</servlet-name>
<url-pattern>/Dif01</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Different</servlet-name>
<url-pattern>/Test01</url-pattern>
</servlet-mapping>
</web-app>
上面的例子中,类中servlet默认名是cn.itcast.servlet.TestServlet01(cn.itcast.servlet是我的servlet包名)。但web.xml中servlet的名称和@WebServlet标注使用的默认名称不同,因此web.xml不重写WebServlet标注中的映射。相反,它补充了@WebServlet标注定义。换句话说,它定义了两个额外的servlet映射给在@WebServlet标注的定义的URL模式列表。因此,现在TestServlet01 servlet 可以被下面的URL映射到。
//@WebServlet
http://localhost:8080/chapter03/TestServlet01
//web.xml
http://localhost:8080/chapter03/Dif01
//web.xml
http://localhost:8080/chapter03/Test01
如果@WebServlet标注和web.xml使用相同的servlet名称,web.xml中的映射会重写由@WebServlet标注中定义的URL映射。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>chapter03</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>cn.itcast.servlet.TestServlet01</servlet-name>
<servlet-class>
cn.itcast.servlet.TestServlet01
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cn.itcast.servlet.TestServlet01</servlet-name>
<url-pattern>/Dif01</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cn.itcast.servlet.TestServlet01</servlet-name>
<url-pattern>/Tset01</url-pattern>
</servlet-mapping>
</web-app>
使用上面的web.xml,和@WebServlet标注隐式使用的servlet名称属性是相同的,此时@WebServlet被重写,则它的url映射将访问不到。 但web.xml中定义的可以被访问。
所以,没有特殊需求还是根据需要只使用其中一个最好,不然这两个的配置很容易出现混乱冲突,搞了好久终于搞出来了。
而且在有@WebServlet的情况下又在web.xml中配置servlet映射,有时候会出现无法启动tomcat服务器的情况:Server Tomcat v8.0 Server at localhost failed to start.这个时候就要查看console窗口具体问题具体分析了。一般都是两个模式的映射出现了冲突
这次学习是因为课程要求必须使用web.xml进行Servlet的映射学习,从一般使用来看,还是@WebServlet更方便一些
学习过程中的参考借鉴:
Servlet3.0及以上如何重写@WebServlet映射