Spring Boot中maven-jaxb2-plugin未生成WSDL全量类的问题求助
问题描述
- 使用
maven-jaxb2-plugin生成对接API的WSDL对应Java类时,仅生成了复杂类型类,login操作的输入输出消息相关类未生成,但SoapUI可正常解析该WSDL。 - 该WSDL中
soapAction参数为空,但Spring WebServiceTemplate调用时要求传入SoapAction,导致调用受阻。
相关配置与代码
pom.xml配置
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <version>0.13.2</version> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <generatePackage>com.test.xxx.soapclient.generated</generatePackage> <generateDirectory>${project.basedir}/src/main/java</generateDirectory> <schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory> <schemaIncludes> <include>*.wsdl</include> </schemaIncludes> </configuration> </plugin> </plugins> </build>
Java调用代码
public Object callWebService(String action, Object request){ return getWebServiceTemplate().marshalSendAndReceive(request,new SoapActionCallback(action)); }
WSDL核心片段
<operation name="login" parameterOrder="user password"> <input message="tns:CardManagementEP_login"> </input> <output message="tns:CardManagementEP_loginResponse"> </output> </operation> <message name="CardManagementEP_loginResponse"> <part name="result" type="xsd:string"> </part> </message> <message name="CardManagementEP_login"> <part name="user" type="xsd:string"> </part> <part name="password" type="xsd:string"> </part> </message> <operation name="login"> <soap:operation soapAction=""/> <input> <soap:body use="literal" namespace="http://com.tch.cards.service"/> </input> <output> <soap:body use="literal" namespace="http://com.tch.cards.service"/> </output> </operation>
问题原因分析
- 类生成不完整:
maven-jaxb2-plugin默认仅生成XML Schema对应的Java类,不会自动生成Web Service服务接口、请求/响应包装类等契约相关代码。WSDL中的operation、message属于服务契约部分,需额外配置才能生成对应代码。 - SoapAction为空问题:WSDL中
soap:operation的soapAction设为空字符串,而Spring原生SoapActionCallback对空值处理不符合部分服务端要求,直接传空可能导致请求被拒绝。
解决办法
一、修复WSDL类生成不完整问题
方案1:使用jaxws-maven-plugin替代(推荐)
替换原maven-jaxb2-plugin为专门生成JAX-WS客户端的jaxws-maven-plugin,配置如下:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-maven-plugin</artifactId> <version>2.3.5</version> <executions> <execution> <goals> <goal>wsimport</goal> </goals> </execution> </executions> <configuration> <wsdlDirectory>${project.basedir}/src/main/resources/wsdl</wsdlDirectory> <packageName>com.test.xxx.soapclient.generated</packageName> <sourceDestDir>${project.basedir}/src/main/java</sourceDestDir> <keep>true</keep> </configuration> </plugin> </plugins> </build>
执行mvn clean compile后,会自动生成包含服务接口、login请求/响应包装类的完整客户端代码。
方案2:修改maven-jaxb2-plugin配置
若坚持使用原插件,需添加JAXB绑定文件:
- 在
src/main/resources下创建bindings.xjb:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" jaxb:version="2.1"> <jaxb:bindings schemaLocation="your-wsdl-file.wsdl" node="/wsdl:definitions"> <jaxb:enableIntrospection>true</jaxb:enableIntrospection> <jaxb:globalBindings> <jaxb:serializable/> </jaxb:globalBindings> </jaxb:bindings> </jaxb:bindings>
- 修改插件配置添加绑定文件引用:
<configuration> <generatePackage>com.test.xxx.soapclient.generated</generatePackage> <generateDirectory>${project.basedir}/src/main/java</generateDirectory> <schemaDirectory>${project.basedir}/src/main/resources/wsdl</schemaDirectory> <schemaIncludes> <include>*.wsdl</include> </schemaIncludes> <!-- 添加绑定配置 --> <bindingDirectory>${project.basedir}/src/main/resources</bindingDirectory> <bindingIncludes> <include>bindings.xjb</include> </bindingIncludes> </configuration>
二、解决SoapAction为空问题
方案1:自定义SoapActionCallback
创建自定义回调类,支持空SoapAction:
import org.springframework.ws.soap.client.core.SoapActionCallback; import javax.xml.transform.TransformerException; import org.springframework.ws.soap.SoapMessage; public class EmptySoapActionCallback extends SoapActionCallback { public EmptySoapActionCallback() { super(""); } @Override protected void doWithMessage(SoapMessage message) throws TransformerException { message.setSoapAction(""); } }
调用时替换原回调:
public Object callWebService(Object request){ return getWebServiceTemplate().marshalSendAndReceive(request, new EmptySoapActionCallback()); }
方案2:直接传入空字符串测试
部分服务端允许空SOAPAction,可直接传入空值尝试:
public Object callWebService(Object request){ return getWebServiceTemplate().marshalSendAndReceive(request, new SoapActionCallback("")); }
若服务端报错,再切换到方案1。
内容的提问来源于stack exchange,提问作者alext
相关产品推荐
相关产品推荐

