web.xml中的cvc-id.3错误

39

在使用Eclipse编辑SpringMVC Web应用的web.xml文件时,我遇到了以下错误信息:

cvc-id.3: 身份约束字段'web-app-servlet-name-uniqueness'与元素'web-app'匹配,但此元素没有简单类型。

这是我的web.xml的部分内容:

<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

错误指向<servlet-name>dispatcher</servlet-name>声明。

我该怎么做才能修复它?

提前感谢您的帮助。


3
错误提示表明servlet-name的唯一性存在问题。我们能否查看整个文件,而不仅仅是那个部分? - skaffman
6个回答

60

我偶然发现将Java改为大写后错误消失了:

xmlns="http://java.sun.com/xml/ns/javaee"

应该是:

xmlns="http://JAVA.sun.com/xml/ns/javaee"


12
今天我遇到了同样的错误。你可以直接使用"Java"而不是"java",这样就能解决问题了……我选择在https中添加一个"s"也能解决错误。这真是有些奇怪…… - Michel
14
使用不同的大小写实际上引入了一个不同的命名空间,因此这并不是一个真正的解决方案。 - MrTux
哦,天啊,那不可能全部是真的。GWT 到底有多过时? - user2618802
1
我验证了将其更改为“JAVA”或“Java”可以解决问题。同时,将URL从“http…”切换到“https…”似乎也可以解决问题。仅仅进行[Project > Clean]并不能解决它。 - Pete Kelley
14
这不是一个答案,人们只是通过将命名空间更改为Eclipse不知道和忽略的内容来隐藏潜在问题。这些建议的效果类似于使用“xmlns =“ foobar””。https://www.liquid-technologies.com/xml-schema-tutorial/xsd-namespaces - Thorsten Schöning
奇怪!这对我也起作用了。 - Shweta Priyadarshani

53

Eclipse 2021-06

今天我遇到了与Eclipse 2021-06类似的问题:

cvc-id.3:身份约束'web-common-filter-name-uniqueness'的字段匹配元素'web-app',但此元素没有简单类型。

错误答案

其他答案中很多建议都是错误的,因为它们所做的事情是将命名空间更改为不再映射到任何模式而且因此不能简单地进行检查。一些评论已经表明了这一点,因此在某些地方将java更改为Javahttp更改为httpsjavaee更改为j2ee只会隐藏问题。

关键是,如果出现该消息,则确实存在需要找到并修复的验证问题。因此,像清除项目、在Windows / Preferences / Network Connections / Cache下清除Eclipse的网络缓存等建议通常都是巫术,它们可能(!)起作用!但是,在我的情况下问题并不在那里。

部署描述符3.1

在我的情况下有效的方法是将部署描述符更改为版本3.1

<web-app    xmlns="http://java.sun.com/xml/ns/javaee"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                                http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
            id="WebApp_ID" version="3.0">

对比。

<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"
            id="WebApp_ID" version="3.1">

之后,验证错误立即消失。不过,重要的是与其他答案中介绍无效/未知/错误/ ... 命名空间不同的是,Eclipse进行了验证!这可以通过真正添加相同的filter-name两次来轻松测试,结果将导致以下错误:

cvc-identity-constraint.4.1:声明为“web-app”的标识约束“web-common-filter-name-uniqueness”的重复唯一值[UrlRewriteFilter]。

这种情况在出现无效/未知/错误/ ... 命名空间时不会发生,Eclipse根本不会进行验证,错误也会被忽略,直到部署甚至更晚的时候才会被发现。

Tomcat+Eclipse版本3.1的支持

我需要自己支持旧应用程序,因此检查了哪个版本的Tomcat已部署相应的web.xml,其版本为8.0。对于许多用户来说,这应该足够老了。当然,Eclipse似乎也已经捆绑了相当长时间的那个版本,否则它就不能进行验证。只需查看文件org.eclipse.jst.standard.schemas_1.2.400.v202101070609.jar

从3.0到3.1的更改

我比较了这两个版本,似乎人们主要只更改了命名空间,并将一些类型从关联的web-common_*.xsd迁移到了web-app_*.xsd本身。除此之外,真正的变化很小。

结论

总体上有趣的问题是为什么Eclipse停止了对先前web.xml的支持,即使它似乎完全正确。只更改了命名空间和版本号,但在过去几年中这也能够工作。我再也不确定旧版的Eclipse是否使用语言服务器进行验证,就像当前使用的版本所做的那样。我想知道任何提供语言服务器的东西可能已经改变,而部署描述符的3.0版本可能根本不再受支持。

或者关于下载和包含web-common_*.xsd发生了什么变化,这就是为什么他们需要将类型重构到父文件中的原因。

当然,当问题实际上在2010年编写时,这两者都不是问题。 :-) 不过,由于部署描述符仍然看起来正确,只是针对某些旧版本,因此肯定还有其他根本原因。

JSP相关更新

我也遇到了与JSP相关的问题,这次只更改XSD的位置就足够了,而不需要进行任何命名空间或版本更改。对于web.xml应用了后者,但这一次我只做了以下操作:

<taglib
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

对比。

<taglib
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd

http://xmlns.jcp.org/xml/ns/javaee/web-jsptaglibrary_2_1.xsd

重要的是我并没有简单地使命名空间无效,但验证仍然适用。可以通过添加无效元素或例如添加具有相同名称的多个函数来轻松测试此功能。

cvc-complex-type.2.4.a: Invalid content was found starting with element '{"http://java.sun.com/xml/ns/javaee":foobar}'. One of '{"http://java.sun.com/xml/ns/javaee":description, "http://java.sun.com/xml/ns/javaee":display-name, "http://java.sun.com/xml/ns/javaee":icon, "http://java.sun.com/xml/ns/javaee":tlib-version}' is expected.

Eclipse中的WWD包含一些目录文件,将同一个XSD文件映射到多个不同的URI名称下。因此,理论上旧的URI仍然可用并被使用,但由于某些原因似乎并没有。另一方面,新的URI出于某种原因似乎可行,但在这些情况下需要保留旧的命名空间!原因很简单,就是无论使用哪个URI来读取它,唯一可用的文件仍包含旧的命名空间。

Eclipse WWD catalog settings

<uri name="http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" uri="file:///C:/Users/tschoening/AppData/Roaming/Eclipse/Java%20Docsrv/configuration/org.eclipse.osgi/1360/0/.cp/dtdsAndSchemas/web-jsptaglibrary_2_1.xsd"/>
<uri name="http://xmlns.jcp.org/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" uri="file:///C:/Users/tschoening/AppData/Roaming/Eclipse/Java%20Docsrv/configuration/org.eclipse.osgi/1360/0/.cp/dtdsAndSchemas/web-jsptaglibrary_2_1.xsd"/>

所以,仅更改URI可能也适用于web.xml,就像在我的JSP标签库中似乎有效一样。同样也没有让任何更新的东西工作,看起来标准已经有所改变,并且我需要采用更多的方法,这是我不想要的遗留问题... :-)


8
请大力点赞这个回答 :) - rineez
对我来说,将它更改为3.1并没有修复错误,但将其更改为2.5则可以。 - Tigris
你实际上使用了问题的定义吗?因为仅更改版本号只会再次隐藏潜在的问题。 - Thorsten Schöning
我接下来想问的一个显而易见的问题是,是否有Eclipse的bug已经被提交了?这真的很烦人,但由于我们当前服务器支持的级别,我还不能改用3.1版本。 - dbreaux
我打开了https://bugs.eclipse.org/bugs/show_bug.cgi?id=577715。 - dbreaux

8
<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:javaee="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">

在你的xmlns="http://java.sun.com/xml/ns/javaee"行中添加一个namespace(例如)xmlns:javaee="http://java.sun.com/xml/ns/javaee"可能会解决你的问题。

两个定义文件中都有元素,所以如果没有适当的名称空间,它们就不会是唯一的。


1
仅使用xmlns:javaee而不使用<javaee:servlet>将只隐藏问题,就像所有其他答案建议将java更改为JAVA或将http更改为https一样。是吗? - Thorsten Schöning

1

我非常感谢Thorsten Schöning的答案并且他提出解决问题而不是掩盖它们的建议。

在我的情况下,由于使用了错误的版本和描述符架构,我得到了这些验证错误。

因为我使用了Jakarta的Servlets实现。

jakarta.servlet:jakarta.servlet-api:5.0.0

我不得不使用雅加达的模式

<web-app version="5.0"
             xmlns="https://jakarta.ee/xml/ns/jakartaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
             id="webappid">

例如,必须使用servlet 5.0版本处理的Jakarta servlet部署描述符实例必须在实例文档的version属性中指示版本,例如“5.0”。部署描述符处理器使用版本信息选择适当版本的模式文档来处理部署描述符实例。
因此,如果您使用javax.servlet-api:3.1,则正确的描述符也应该使用相应的版本。就像这样:
<web-app version="3.1"
         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"
         id="webappid">

曾经历过,已经完成。 对于Spring 6 / Java 17的世界,我最终得到了以下结果: <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://jakarta.ee/xml/ns/jakartaee" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd" version="6.0"> - andrej

1
请查看下面的web.xml标签。
<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">

</web-app>

请详细说明为什么这样做可以解决问题。没有详细信息并不能提供太多帮助。 - trebor

-5

我在这里找到了以下链接链接,对我很有帮助:

<web-app
  xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  version="2.5">

属性xmlns的值以j2ee结尾,而不是javaee


1
不要跟随那些在他们的XML示例中使用ISO-8859-1的人。:-) j2eejavaee模式位置的组合没有太多意义。schemaLocation将命名空间映射到文件,而javaee则未被导入/使用。另一方面,j2ee未在schemaLocation中提及,因此解析器根本不会进行验证。这就是为什么错误会消失的原因。https://dev59.com/Gm025IYBdhLWcg3wqX1o#5875404 - Thorsten Schöning

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接