使用Maven JAXB2插件生成多WebService类时包混乱的解决方法
解决maven-jaxb2-plugin多WSDL生成代码包混杂问题
这个问题我之前也碰到过,根源在于maven-jaxb2-plugin的默认行为会让多个execution共享部分生成上下文,再加上JAXB会优先根据WSDL中的命名空间自动映射包路径,而你指定的<generatePackage>只是作为默认包,当不同WSDL存在关联命名空间或者JAXB解析逻辑重叠时,就会出现类文件跨包混杂的情况。
下面是几个关键的解决步骤,结合修改后的POM配置来说明:
1. 给每个Execution指定独立的生成目录
每个WSDL的代码生成到单独的目录下,避免互相干扰,同时Maven会自动把这些目录加入编译源路径。
2. 开启严格模式强制命名空间与包的映射
添加<strict>true</strict>配置,让JAXB严格按照你指定的包来生成代码,拒绝将不属于当前命名空间的类放入该包。
3. 清空输出目录避免残留旧代码
添加<clearOutputDir>true</clearOutputDir>,确保每次执行该execution时,只会保留当前WSDL生成的代码,不会残留之前的生成文件。
4. (可选)使用绑定文件明确命名空间映射
如果WSDL中的命名空间和你指定的包名不匹配,JAXB还是会按照命名空间来放置类,这时候可以创建绑定文件(比如bus-binding.xjb)来强制绑定命名空间到目标包,然后在对应的execution中指定该文件。
修改后的完整POM配置
<plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <!-- maven-jaxb2-plugin --> <plugin> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <executions> <execution> <id>Bus</id> <goals> <goal>generate</goal> </goals> <configuration> <schemaLanguage>WSDL</schemaLanguage> <schemas> <schema> <url>http://server/Service1?wsdl</url> </schema> </schemas> <generatePackage>com.core.business</generatePackage> <!-- 指定独立生成目录 --> <generateDirectory>${project.build.directory}/generated-sources/jaxb/bus</generateDirectory> <!-- 开启严格模式 --> <strict>true</strict> <!-- 清空输出目录 --> <clearOutputDir>true</clearOutputDir> <!-- 可选:绑定文件 --> <!-- <bindingFiles> <bindingFile>src/main/resources/bus-binding.xjb</bindingFile> </bindingFiles> --> </configuration> </execution> <execution> <id>Ser</id> <goals> <goal>generate</goal> </goals> <configuration> <schemaLanguage>WSDL</schemaLanguage> <schemas> <schema> <url>http://server/Service2?wsdl</url> </schema> </schemas> <generatePackage>com.core.search</generatePackage> <generateDirectory>${project.build.directory}/generated-sources/jaxb/search</generateDirectory> <strict>true</strict> <clearOutputDir>true</clearOutputDir> <!-- <bindingFiles> <bindingFile>src/main/resources/search-binding.xjb</bindingFile> </bindingFiles> --> </configuration> </execution> <execution> <id>Tab</id> <goals> <goal>generate</goal> </goals> <configuration> <schemaLanguage>WSDL</schemaLanguage> <schemas> <schema> <url>http://server/Service3?wsdl</url> </schema> </schemas> <generatePackage>com.core.table</generatePackage> <generateDirectory>${project.build.directory}/generated-sources/jaxb/table</generateDirectory> <strict>true</strict> <clearOutputDir>true</clearOutputDir> <!-- <bindingFiles> <bindingFile>src/main/resources/table-binding.xjb</bindingFile> </bindingFiles> --> </configuration> </execution> </executions> </plugin> </plugins>
绑定文件示例(bus-binding.xjb)
如果需要强制命名空间映射,可以创建如下绑定文件:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" version="2.1"> <!-- 绑定对应的WSDL命名空间 --> <jaxb:bindings schemaLocation="http://server/Service1?wsdl" node="/wsdl:definitions"> <jaxb:schemaBindings> <jaxb:package name="com.core.business"/> </jaxb:schemaBindings> </jaxb:bindings> </jaxb:bindings>
这样配置后,每个WSDL生成的代码会严格限制在你指定的包目录下,不会再出现混杂的情况。
内容的提问来源于stack exchange,提问作者Mythbuster
相关产品推荐
相关产品推荐

