报错现场还原
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
来源:简书