Jersey JAX-RS服务WADL中grammar元素为空,XML Schema未显示
看起来你遇到的是Jersey默认不会自动关联自定义XML Schema到WADL的常见问题,尤其是当使用JAXBElement包装实体类时,需要显式配置才能让Schema出现在WADL的grammar部分。下面是几个无需额外依赖的解决方案,适配你的ANT编译、不能添加额外库的场景:
1. 正确放置XML Schema并确保可访问
首先把你的parent.xsd放到Web应用的WEB-INF/schemas目录下(这个目录默认受保护,不会直接被外部访问,但Jersey内部可以读取),或者如果想让外部能直接访问,放到WebContent/schemas目录下。
验证路径是否正确:如果放在WebContent/schemas,启动应用后尝试访问http://localhost:8080/Example/rest/schemas/parent.xsd,应该能看到Schema内容。
2. 配置Jersey的WadlGenerator关联Schema
在你的web.xml中,给Jersey的ServletContainer添加两个初始化参数,使用Jersey自带的WadlGeneratorGrammarGenerator来指定Schema路径:
<servlet> <servlet-name>Jersey RESTful Application</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>io.swagger.jaxrs.listing, it.example</param-value> </init-param> <!-- 添加以下两个参数 --> <init-param> <param-name>jersey.config.server.wadl.generator</param-name> <param-value>org.glassfish.jersey.server.wadl.internal.generators.WadlGeneratorGrammarGenerator</param-value> </init-param> <init-param> <param-name>jersey.config.server.wadl.generator.grammar.schemaUrl</param-name> <param-value>/WEB-INF/schemas/parent.xsd</param-value> </init-param> <!-- 多个Schema用逗号分隔,比如:/WEB-INF/schemas/parent.xsd,/WEB-INF/schemas/child.xsd --> <load-on-startup>1</load-on-startup> </servlet>
这个配置会让Jersey在生成WADL时,自动将指定的Schema引用添加到grammar元素中。
3. 确保JAXB生成类包含Schema位置信息
当你用xjc生成Parent类时,添加-schemaLocation参数,让生成的类带有@XmlSchema注解,指定Schema的访问路径:
xjc -d src -p it.example parent.xsd -schemaLocation http://localhost:8080/Example/rest/schemas/parent.xsd
生成的package-info.java会包含类似这样的注解:
@XmlSchema( namespace = "...", schemaLocation = "http://localhost:8080/Example/rest/schemas/parent.xsd" ) package it.example;
这会帮助Jersey更准确地识别实体类对应的Schema,进一步确保WADL中能正确引用。
为什么之前的尝试无效?
Jersey默认只会自动关联JDK内置的XML Schema或者Jersey自身的Schema,对于自定义的Schema,必须显式指定路径。另外,使用JAXBElement包装实体类时,Jersey无法直接从包装类推断出对应的Schema,所以需要通过上述配置来手动关联。
内容的提问来源于stack exchange,提问作者Tu.Ma.

