報錯現場還原
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.
或者是下面這種錯誤
Invalid content was found starting with element '{"http://xmlns.jcp.org/xml/ns/javaee":servlet-class}'.
One of '{"http://xmlns.jcp.org/xml/ns/javaee":description, "http://xmlns.jcp.org/xml/ns/javaee":display-name,
"http://xmlns.jcp.org/xml/ns/javaee":icon, "http://xmlns.jcp.org/xml/ns/javaee":servlet-name}' 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 之前。到這里,我們終於明白了錯誤的原因是我們將子元素的前后順序設置錯了。
部分來自於:https://www.jianshu.com/p/76ac93a79751
來源:簡書
