web.xml文件报错:cvc-complex-type.2.4.a: Invalid content was found starting with element 'init-param'

报错现场还原

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_3_1.xsd"
         version="3.1">

报错的 servlet 元素如下:

<servlet>
    <description>Enter Dispatcher</description>
    <servlet-name>xxxMVC</servlet-name>
    <servlet-class>com.xxx.web.servlet.RequestDispatcher</servlet-class>
    <load-on-startup>1</load-on-startup>
    <init-param>
        <param-name>xxxName</param-name>
        <param-value>xxxValue</param-value>
    </init-param>
</servlet>

报错提示在 <init-param> 那一行,具体报错内容如下:

cvc-complex-type.2.4.a: Invalid content was found starting with element 'init-param'. One of '{"http://xmlns.jcp.org/xml/ns/javaee":enabled, 
 "http://xmlns.jcp.org/xml/ns/javaee":async-supported, "http://xmlns.jcp.org/xml/ns/javaee":run-as, "http://xmlns.jcp.org/xml/ns/javaee":security-
 role-ref, "http://xmlns.jcp.org/xml/ns/javaee":multipart-config}' is expected.

解决方法

init-param 元素整体移动到 load-on-startup 元素之前,修改后,内容如下:

<servlet>
    <description>Enter Dispatcher</description>
    <servlet-name>xxxMVC</servlet-name>
    <servlet-class>com.xxx.web.servlet.RequestDispatcher</servlet-class>
    <init-param>
        <param-name>xxxName</param-name>
        <param-value>xxxValue</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

报错原因分析

因为是 servlet 元素报错,所以,我们尝试找到对应的xsd文件,来看下报错的地方违反了哪条限制或约束。根据xml文件头部声明,我们知道对应的xsd文件是 http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd ,但是从 web-app_3_1.xsd 文件中,我们并没有找到对应的约束定义。但是,我们发现如下代码片段:

<xsd:include schemaLocation="web-common_3_1.xsd"/>

所以,我们尝试继续在 web-common_3_1.xsd 中寻找对应的限制或约束,我们找到如下两个代码片段:

<xsd:element name="servlet" type="javaee:servletType"/>
<xsd:complexType name="servletType">
    ......
    <xsd:sequence>
        ......
        <xsd:element name="init-param"
                     type="javaee:param-valueType"
                     minOccurs="0"
                     maxOccurs="unbounded"/>
        <xsd:element name="load-on-startup"
                     type="javaee:load-on-startupType"
                     minOccurs="0">
        </xsd:element>
        ......
    </xsd:sequence>
    ......
</xsd:complexType>

从上面两段代码,我们知道,针对 servlet 元素,通过 <xsd:sequence> 限制了子元素的出现顺序,init-param 必须出现在 load-on-startup 之前。到这里,我们终于明白了错误的原因是我们将子元素的前后顺序设置错了。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本章聊一聊ServletContext 3.0规范中定义的注解以及在web应用中使用的框架和库的可插拔性的提升。 ...
    Lucky_Micky阅读 6,091评论 0 3
  • 对于java中的思考的方向,1必须要看前端的页面,对于前端的页面基本的逻辑,如果能理解最好,不理解也要知道几点。 ...
    神尤鲁道夫阅读 842评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,993评论 19 139
  • Linux 上的压缩包文件格式,除了 Windows 最常见的*.zip、*.rar、.7z 后缀的压缩文件,还有...
    e9f3ca3721bc阅读 2,804评论 0 0
  • 干活 干了一下午活,好累!但很充实!!!
    傅深钊傅深钊阅读 209评论 0 1