Caused by: java.lang.IllegalArgumentException: servlet映射中的<url pattern>[hello]无效

目录

下面是web.xml中详解

 下面是有关url-pattern的设置与匹配

           (1):  精确路径模式

        (2):通配符路径模式:

           (3):全路径模式(4)后缀名模式:    

匹配原则:

        (1):路径优先后缀匹配原则

        (2):精确路径优先匹配原则

        (3) :最长路径优先匹配原则:


 在用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()方法,其实也可以划分到第二个匹配原则中)

  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JAVA技术开发员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值