目录
在用Maven写javaweb程序时,运行Servlet程序时发生错误
Caused by: java.lang.IllegalStateException: 启动子级时出错
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:686)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:658)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:662)
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1782)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:294)
... 35 more
Caused by: org.apache.catalina.LifecycleException: 无法启动组件[StandardEngine[Catalina].StandardHost[localhost].StandardContext[/s1]]
at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:440)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:683)
... 43 more
Caused by: java.lang.IllegalArgumentException: servlet映射中的<url pattern>[hello]无效
at org.apache.catalina.core.StandardContext.addServletMappingDecoded(StandardContext.java:3040)
at org.apache.catalina.Context.addServletMappingDecoded(Context.java:905)
at org.apache.catalina.startup.ContextConfig.configureContext(ContextConfig.java:1563)
at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1336)
at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:987)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:304)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4852)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
... 44 more
[2023-05-25 11:34:45,503] Artifact servlet:war: Error during artifact deployment. See server log for details.
25-May-2023 23:34:54.575 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [E:\tomcat\apache-tomcat-9.0.75\webapps\manager]
25-May-2023 23:34:54.926 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[E:\tomcat\apache-tomcat-9.0.75\webapps\manager]的部署已在[351]毫秒内完成
开始以为是web.xml文件没有配置好,网上找了最新的重新配置了一下
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_4_0.xsd"
version="4.0"
metadata-complete="true">
</web-app>
后来以为是包的版本有问题,在Maven仓库里重新导了javax.servlet.jsp包,https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api/2.3.1
在总项目里的pom.xml文件里修改了需要的依赖包
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
结果还是不行,又搜了搜出错误的报告里的关键字,servlet映射中的<url pattern>[hello]无效
最后找到了原因,是我的<url pattern>标签里的路径没写好。
正常的应该是这样的:<url-pattern>/hello</url-pattern>
而我没有仔细看,没有带/
下面是web.xml中<url-pattern>详解
标签<url-pattern>
<url-pattern>是我们用Servlet做Web项目时需要经常配置的标签,例:
<servlet>
<servlet-name>index</servlet-name>
<servlet-class>com.we.servlet.IndexServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>index</servlet-name>
<url-pattern>/index</url-pattern>
</servlet-mapping>
当我们在浏览器的地址栏里输入http://localhost:8080/we/index时[假设我部署在webapps目录下的项目名为we,
就会匹配到我们指定的<url-pattern>中,即/index然后一步一步找到对应的<servlet-class>
那我们输入的URL:http://localhost:8080/we/index又是如何与<url-pattern>中的/index匹配的呢?
首先我们要知道URL的组成
http://localhost:8080 我们可以理解为是我们的服务器地址,而该地址之后的部分我们统称为:RequestURI
RequestURI是我们需要重点注意的部分,其又可以分解为几部分
/we 是我们的ServletConext的上下文地址,我们称为ServletContext Path,可以简单理解为部署项目时的webapps目录下的项目名
/index 是我们的Servlet的地址,我们称为Servlet Path,这里就是需要与我们的<url-pattern>匹配的内容
注:在/index后边我们还可以跟其他的信息,例如:/index?name=admin&pass=admin 这是其中一种明文表示的方式
标签<url-pattern>中*的使用
我们知道在写<url-pattern>时有一种通配符的使用写法,即*
1.当我使用<url-pattern>/*</url-pattern>时,我们可以匹配所有的请求,即所有的请求都会经过该标签对应的Servlet
此时就需要注意静态资源的请求,因为当我们使用http://localhost:8080/we/login.html时,依然会匹配该Servlet,
而很多静态资源其实是不需要经过Servlet的,例如:js,css,html,jsp,img等静态资源文件,此时就需要在该Servlet中对静态资源做特殊处理
2.如果配有如下两个<url-pattern>标签时,URL地址为http://localhost:8080/we/index时又是如何匹配的呢?
<url-pattern>/index</url-pattern>
<url-pattern>/*</url-pattern>
上边我们已经说过,/*可以匹配所有的请求,而/index也可以匹配我们的URL地址,此时URL地址会自动且优先的进行精确匹配,即/index,
且只匹配一次,也就是说一旦匹配到一个Servlet即执行该Servlet不再对其他Servlet进行匹配,
当我们输入一个http://localhost:8080/we/login时,由于此时匹配不到/login所以只能匹配/*了
3.在Servlet Path部分我们还可以使用更精确的匹配,例如:
<url-pattern>/index/login</url-pattern>匹配http://localhost:8080/we/index/login
<url-pattern>/index/logout</url-pattern>匹配http://localhost:8080/we/index/logout
此时/index/login和/index/logout才是我们的Servlet Path
4.我们可以通过使用<url-pattern>*.do</url-pattern>来过滤请求,
这样如果我们在页面中的请求中添加后缀名.do就可以避免对静态资源的过滤了,也就不需要对静态资源做特殊处理了
url-pattern大致分为以下几种方式
完全匹配 如:<url-pattern>/servlet/MyServlet.do</url-pattern>
目录匹配 如:<url-pattern>/servlet/*</url-pattern>
扩展名匹配 如:<url-pattern>*.do</url-pattern>
下面是有关url-pattern的设置与匹配
Servlet中url-pattern的设置与匹配
-
<url-pattern/>的设置:
-
(1): 精确路径模式:请求路径必须与<url-pattern>的值完全相同才可被当前Servlet处理.
-
例如:<servlet-mapping>
<servlet-name>someServlet</servlet-name>
<url-pattern>/xxx/ooo/jjj/some</url-pattern>
<url-pattern>/xxx/some</url-pattern>
<url-pattern>/some</url-pattern>
</servlet-mapping> -
(2):通配符路径模式: 该模式中的路径由两部分组成:精确路径部分与通配符部分。请求路径中只有携带了<url-pattern/>值中指定的精确路径部分才可被当前Servlet处理。
-
例如:<servlet-mapping>
<servlet-name>secondServlet</servlet-name>
<url-pattern>/aaa/*</url-pattern>
</servlet-mapping> -
(3):全路径模式: 例如: <servlet-mapping>
<servlet-name>secondServlet</servlet-name>
<!-- <url-pattern>/*</url-pattern> -->
<!-- /*与/都是全路径模式,但它们还是有不同的
/*是真正的全路径模式,可以拦截所有请求,无论是动态资源请求(.jsp),还是静态资源请求(.html),均会被拦截。
/只会拦截静态资源请求,对于动态资源请求是不进行拦截的。
-->
<url-pattern>/</url-pattern>
</servlet-mapping> -
(4)后缀名模式:<servlet-mapping>
<servlet-name>secondServlet</servlet-name>
<!-- <url-pattern>/</url-pattern> -->
<url-pattern>*.do(.后面随意,只不过后面有的框架用的都是.action或者.do)</url-pattern>
</servlet-mapping> -
后缀名模式的用法限制:为<url-pattern/>设置值时,带斜杠的通配符路径模式与后缀名模式不能同时使用,例如,不能使用/*.do, /xxx/*.do等形式。否则,服务器将无法正常启动.
-
匹配原则: (1):路径优先后缀匹配原则:就是这个请求按照路径方式能匹配上,按照后缀方式也能匹配上,这时候路径优先于后缀名。
-
(2):精确路径优先匹配原则:比如说/xxx/*和/xxx/ls它会优先执行/xxx/ls.
-
(3) :最长路径优先匹配原则:比如说/xxx/*和/xxx/ooo/*,用户提交请求/xxx/ooo/dada时,会优先执行最长路径的Servlet.(就是执行/xxx/ooo/dada所对应的Servlet的service()方法,其实也可以划分到第二个匹配原则中)