参考资料 SpringBoot2 整合 XFIRE 服务端和客户端_springboot xfire_gblfy的博客-CSDN博客
Attribute “singleton” must be declared for element type “bean”._singletonattribute-CSDN博客
原因 某项目有个使用了xfire框架的webservice服务,报错:
sap pi中间件请求会出现此问题,但soapui请求不会,为了在soapui上复现该问题,搭建了一个xfire服务
搭建 pom 注意springboot版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 <?xml version="1.0" encoding="UTF-8" ?> <project xmlns ="http://maven.apache.org/POM/4.0.0" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation ="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" > <modelVersion > 4.0.0</modelVersion > <parent > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-parent</artifactId > <version > 2.5.4</version > <relativePath /> </parent > <groupId > org.example</groupId > <artifactId > xfiretest</artifactId > <version > 1.0-SNAPSHOT</version > <properties > <maven.compiler.source > 6</maven.compiler.source > <maven.compiler.target > 6</maven.compiler.target > </properties > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter</artifactId > </dependency > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-web</artifactId > </dependency > <dependency > <groupId > org.codehaus.xfire</groupId > <artifactId > xfire-all</artifactId > <version > 1.2.6</version > <exclusions > <exclusion > <groupId > javax.activation</groupId > <artifactId > activation</artifactId > </exclusion > <exclusion > <groupId > org.springframework</groupId > <artifactId > spring</artifactId > </exclusion > <exclusion > <artifactId > commons-logging</artifactId > <groupId > commons-logging</groupId > </exclusion > <exclusion > <artifactId > stax-api</artifactId > <groupId > stax</groupId > </exclusion > </exclusions > </dependency > </dependencies > </project >
/resources/config/boot-xfire.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns ="http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:context ="http://www.springframework.org/schema/context" xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd" > <context:component-scan base-package ="com.xfire" /> <import resource ="classpath:org/codehaus/xfire/spring/xfire.xml" /> <bean id ="webAnnotations" class ="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations" /> <bean id ="jsr181HandlerMapping" class ="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping" > <property name ="xfire" ref ="xfire" /> <property name ="webAnnotations" ref ="webAnnotations" /> </bean > </beans >
XFireTestApplication 1 2 3 4 5 6 @SpringBootApplication public class XFireTestApplication { public static void main (String[] args) { SpringApplication.run(XFireTestApplication.class, args); } }
WebApplicationContextLocator 用于获取当前上下文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package com.xfire;import org.springframework.boot.web.servlet.ServletContextInitializer;import org.springframework.context.annotation.Configuration;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.context.support.WebApplicationContextUtils;import javax.servlet.ServletContext;import javax.servlet.ServletException;@Configuration public class WebApplicationContextLocator implements ServletContextInitializer { private static WebApplicationContext webApplicationContext; public static WebApplicationContext getCurrentWebApplicationContext () { return webApplicationContext; } @Override public void onStartup (ServletContext servletContext) throws ServletException { webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext); } }
SpringBootBeanAutowiringSupport 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 package com.xfire;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;import org.springframework.util.Assert;import org.springframework.util.ClassUtils;import org.springframework.web.context.WebApplicationContext;public class SpringBootBeanAutowiringSupport { private static final Logger logger = LoggerFactory.getLogger(SpringBootBeanAutowiringSupport.class); public SpringBootBeanAutowiringSupport () { System.out.println("SpringBootBeanAutowiringSupport.SpringBootBeanAutowiringSupport" ); processInjectionBasedOnCurrentContext(this ); } public static void processInjectionBasedOnCurrentContext (Object target) { Assert.notNull(target, "Target object must not be null" ); WebApplicationContext cc = WebApplicationContextLocator.getCurrentWebApplicationContext(); if (cc != null ) { AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor (); bpp.setBeanFactory(cc.getAutowireCapableBeanFactory()); bpp.processInjection(target); } else { if (logger.isDebugEnabled()) { logger.debug("Current WebApplicationContext is not available for processing of " + ClassUtils.getShortName(target.getClass()) + ": " + "Make sure this class gets constructed in a Spring web application. Proceeding without injection." ); } } }}
XfireConfig 引入配置以及注册xfire servlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package com.xfire;import org.codehaus.xfire.spring.XFireSpringServlet;import org.springframework.boot.web.servlet.ServletRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ImportResource;import org.springframework.stereotype.Component;@ImportResource(locations = {"classpath:config/boot-xfire.xml"}) @Component public class XfireConfig { @Bean public ServletRegistrationBean registrationBean () { ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean (); servletRegistrationBean.setServlet(new XFireSpringServlet ()); servletRegistrationBean.addUrlMappings("/webservice/*" ); return servletRegistrationBean; } }
IXfireService 定义接口
1 2 3 4 5 6 7 8 9 10 11 package com.xfire;public interface IXfireService { public String sayHello (String info) ; public String sayHello2 (String info,String info2) ; }
XfireServiceImpl 实现接口以及定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @WebService(serviceName = "xfireTestService", targetNamespace = "http://nothing.com") @BindingType(value = SOAPBinding.SOAP12HTTP_BINDING) @Service public class XfireServiceImpl extends SpringBootBeanAutowiringSupport implements IXfireService { @Override public String sayHello (String info) { return "sayHello:" + info; } @Override public String sayHello2 (String info, String info2) { return info + info2; } }
启动问题
Attribute “singleton” must be declared for element type “bean”
解决,找到jar包,坐标 xfire-all-1.2.6.jar\org\codehaus\xfire\spring
其中两个文件xfire.xml和xfireXmlBeans.xml,删除其中所有的singleton=”true”
cannot convert value of type ‘org.codehaus.xfire.spring.editors.ServiceFactoryEditor’
解决:找到同文件夹中的 customEditors.xml,找到如下代码,删除property属性
1 2 3 4 5 <entry key ="org.codehaus.xfire.service.ServiceFactory" > <bean class ="org.codehaus.xfire.spring.editors.ServiceFactoryEditor" > <property name ="transportManager" ref ="xfire.transportManager" /> </bean > </entry >
运行&解决问题 访问地址 localhost:8080//webservice/xfireTestService?wsdl
使用soapui进行测试,发现在body缺失时会报该错,最后发现是pi中间件原本有个功能是使用soap的格式包装数据,但通道配置给取消了,恢复该配置即可