两个使用WebServiceTemplate的Maven项目合并报JAXB异常如何解决
问题根源
两个项目的Spring Bean使用了相同id,合并到同一个Spring容器时,后加载的Bean会覆盖先加载的:两个项目都定义了id为webServiceTemplate、marshaller、unMarshaller的Bean,项目2的Marshaller上下文只包含自身服务的类路径,覆盖了项目1的Marshaller后,自然无法识别项目1的org.com.project1.cm.CreateRequest类。
解决方案
方案1:给不同项目的Bean配置唯一ID(推荐)
- 改造项目1的Spring配置,给Bean加唯一标识:
<bean id="project1WebServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate"> <property name="messageSender"> <bean class="org.springframework.ws.transport.http.HttpComponentsMessageSender"> <property name="credentials" ref="credentialProvider" /> <property name="authScope" ref="authScope" /> <property name="httpClient" ref="httpClient" /> </bean> </property> <property name="defaultUri" value="${myproject.endpoint.url}"/> <property name="marshaller" ref="project1Marshaller" /> <property name="unmarshaller" ref="project1UnMarshaller" /> <property name="interceptors"> <list> <bean class="org.com.project1.cm.SoapLoggingInterceptor" /> </list> </property> </bean> <oxm:jaxb2-marshaller id="project1Marshaller" contextPath="org.com.project1.cm"/> <oxm:jaxb2-marshaller id="project1UnMarshaller" contextPath="org.com.project1.cm" />
- 同理改造项目2的配置,BeanID以
project2为前缀,Marshaller的contextPath保留项目2的路径,同时把WSSE安全拦截器加到project2WebServiceTemplate的拦截器列表中即可。 - 对应业务Impl类注入Template时指定Bean名称:如果用注解注入,使用
@Resource(name = "project1WebServiceTemplate")或者@Autowired + @Qualifier("project1WebServiceTemplate")指定注入对应项目的Template。
方案2:合并JAXB上下文路径(仅适合两个项目JAXB类无重名场景)
如果不想维护两个Marshaller,可直接合并contextPath,多个包路径用冒号分隔即可:
<oxm:jaxb2-marshaller id="commonMarshaller" contextPath="org.com.project1.cm:org.com.project2.cm"/>
两个项目的WebServiceTemplate都共用这个Marshaller即可。
额外检查项
统一两个项目的Spring、Spring-WS依赖版本,避免版本冲突导致的未知问题:项目2引入的spring-expression:4.2.5.RELEASE、spring-ws-security:2.3.1.RELEASE需要和项目1已有的Spring核心版本匹配,避免版本不一致引发的类加载异常。
内容的提问来源于stack exchange,提问作者saathvik
相关产品推荐
相关产品推荐

