Tomcat8.0 Servlet3.0及以上,web.xml与@WebServlet映射问题及其处理

我使用的开发环境:
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映射

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值