springboot集成webservice以及遇到的问题
需求
公司最近需要做⼀个soap请求数据接⼝,由于没有webservice的服务端,⽽系统项⽬使⽤的是springboot框架,所以索性⽤springboot集成⼀个webservice框架⽤作发布服务,以便⽅便为后⾯的soap接⼝提供数据。
如果这篇⽂章不是您想的,请看这篇:
所需依赖
<!-- CXF webservice -->
<dependency>
<groupId>f</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.1.11</version>
</dependency>
<!-- CXF webservice -->
服务端(webserviceServer)
⼀、接⼝及实现类:
接⼝:
@WebService
@Component
public interface TestService {
@WebMethod
String getUserName(@WebParam(name = "id") String id) throws UnsupportedEncodingException;
@WebMethod
public User getUser(String id) throws UnsupportedEncodingException;
}
====================================================================
实现类:
//name暴露服务名称, targetNamespace:命名空间,设置为接⼝的包名倒写(默认是本类包名倒写). endpointInterface接⼝地址
@WebService(name = "test" ,targetNamespace ="f/" ,endpointInterface = "f.webservice.TestService")
@Component
public class TestServiceImpl implements TestService {
JSONResult jsonResult = JsonResult();
@Override
public String getUserName(String id) throws UnsupportedEncodingException {
JSONResult result= JsonResult();
result.setSuccess(true);
result.setMessage("lisi");
JsonObject();
}
@Override
public User getUser(String id)throws UnsupportedEncodingException {
return new User(2L,"zhangsan");
}
}
⼆、发布服务:
发布服务有2种⽅式:
1. 直接在启动类使⽤Endpoint,不需要配置类,但这种⽅式需要jetty依赖,端⼝号可以不和启动类⼀致,可以⾃定义(切勿冲突)
2. 使⽤配置类,不⽤在启动类中加Endpoint.publish。这种⽅式的端⼝号与启动类⼀致
下⾯我们⽤到的是配置类⽅式:
@Configuration
public class CxfConfig {
@Autowired
private Bus bus;
@Autowired
private TestService testService;
//默认servlet路径/*,可⾃定义
@Bean
public ServletRegistrationBean dispatcherServlet() {
return new ServletRegistrationBean(new CXFServlet(), "/services/*");
}
//终端路径
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, appService);
endpoint.publish("/user");
return endpoint;
}
}
启动服务
@SpringBootApplication
public class WebserviceApplication {
public static void main(String[] args) {
SpringApplication.run(WebserviceApplication.class, args);
}
}
然后就可以访问服务了,
访问地址:localhost:port/services/user?wsdl
如果出新内容,则成功~~
客户端(webserviceClient)
调⽤服务的时候有2种⽅式:
1. 代理类⼯⼚
2. 动态调⽤
代码如下:
/**
* 使⽤代理类⼯⼚
*/
public static void test1() {
try {
/
/ 代理⼯⼚
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
// 设置代理地址
jaxWsProxyFactoryBean.setAddress(address);
// 设置接⼝类型
jaxWsProxyFactoryBean.setServiceClass(TestService.class);
// 创建⼀个代理接⼝实现
TestService cs = (TestService) ate();
// 数据准备
String LineId = "1";
// 调⽤代理接⼝的⽅法调⽤并返回结果
User result = (User(LineId);
System.out.println("返回结果:" + result);
//返回值为:返回结果:User{id=1, name='lisi'}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 动态调⽤⽅式
*/
public static void test2() {
/
/ 创建动态客户端
JaxWsDynamicClientFactory dcf = wInstance();
Client client = ateClient(address);
Object[] objects = new Object[0];
try {
// invoke("⽅法名",参数1,参数2,参数3....);
objects = client.invoke("getUserName", "1");
System.out.println("返回数据:" + objects[0]);
//返回值为:返回数据:{"result":{},"success":true,"message":"zhangsan"}
} catch (Exception e) {
e.printStackTrace();
}
}
}
期间遇到的问题:
1. 在⽹上百度了许多答案后,发现他们中的配置类第⼀个@bean的⽅法名都是:
public ServletRegistrationBean dispatcherServlet(){....}
然后就会抛出⼀个异常:
Action:
Consider revisiting the entries above or defining a bean of type 'org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath' in your configu
其实他抛出这样的异常原因是因为他的⽅法名与springMVC中dispatcherServlet相同,程序会默认为是重写,所以会抛出此异常;
处理⽅法为:
将⽅法名改⼀下就ok
2. 如果出现以下异常:
Caused by: f.binding.soap.SoapFault: Unmarshalling Error: 意外的元素 (uri:"", local:"id")。所需元素为<{}arg1>,<{}arg0>
需要检查⾃⼰的参数是否正确,如果确认没错的话,就需要检查⼀下接⼝那块是否有@WebParam修饰
3. 如果后台console出现⽇志如下图所⽰:
这种代表发布成功,但是访问wsdl页⾯的时候404,出现这种情况需要排查以下情况:
1. 仔细检查url路径,尤其是⼤⼩写;
2. 仔细检查的拦截路径,看是否被拦截;
4. 如果出现以下异常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'endpoint' defined in class path resource [com/citi/gpf/ah/config/Endpo at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.13.RELE at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.jav at org.springframework.beans.factory.ateBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[s at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-b at org.springframework.beans.factory.ateBean(AbstractAutowireCapableBeanFactory.java:483) ~
[spring-bea at org.springframework.beans.factory.support.Object(AbstractBeanFactory.java:306) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RE at org.springframework.beans.factory.Singleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.13.RELE at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RE at org.springframework.beans.factory.Bean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEA at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.1 at t.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-4.3.13 at t.fresh(AbstractApplicationContext.java:543) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.R at org.t.fresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.9.RE at org.springframework.fresh(SpringApplication.ja
va:693) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.freshContext(SpringApplication.java:360) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at com.citi.gpf.ah.AHServicesApp.main(AHServicesApp.java:17) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [l.ws.Endpoint]: Factory method 'endpoint' threw exception; nes at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.13.RELEASE.ja at org.springframework.beans.factory.support.ConstructorReso
lver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.13.RELE ... 18 common frames omitted
... 18 common frames omitted
Caused by: l.ws.WebServiceException: f.service.factory.ServiceConstructionException
at f.jaxws.EndpointImpl.doPublish(EndpointImpl.java:375) ~[cxf-rt-frontend-jaxws-3.2.1.jar:3.2.1]
at f.jaxws.EndpointImpl.publish(EndpointImpl.java:255) ~[cxf-rt-frontend-jaxws-3.2.1.jar:3.2.1]
at com.citi.dpoint(EndpointConfig.java:23) ~[classes/:na]
at com.citi.fig.EndpointConfig$$EnhancerBySpringCGLIB$$dd140a18.CGLIB$endpoint$0(<generated>) ~[classes/:na]
at com.citi.fig.EndpointConfig$$EnhancerBySpringCGLIB$$dd140a18$$FastClassBySpringCGLIB$$dbcd1e21.invoke(<generated>) ~[classes/:na] at lib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at t.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) ~[spring-con at com.citi.fig.EndpointConfig$$EnhancerBySpringCGLIB$$dpoint(<generated>) ~[classes/:na]
flect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_152]
flect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_152]
flect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_152]
at flect.Method.invoke(Method.java:498) ~[na:1.8.0_152]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.13.RELEASE.ja ... 19 common frames omitted
Caused by: f.service.factory.ServiceConstructionException: null
at f.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:329) ~[cxf-rt-databinding-jaxb-3.2.1.jar:3.2.1]
at f.service.factory.AbstractServiceFactoryBean.initializeDataBindings(AbstractServiceFactoryBean.java:86) ~[cxf-core-3.2.1.jar:3.2.1]
at f.wsdl.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:470) ~[cxf-rt-wsdl-3.2.1.jar:3.2 at f.jaxws.support.JaxWsServiceFactoryBean.buildServiceFromClass(JaxWsServiceFactoryBean.java:695) ~
[cxf-rt-frontend-jaxws-3.2.1.jar:3.2.1 at f.wsdl.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:530) ~[cxf-rt-wsdl-3.2.1.jar:3.2.1 at f.wsdl.service.ate(ReflectionServiceFactoryBean.java:263) ~[cxf-rt-wsdl-3.2.1.jar:3.2.1]
at f.jaxws.ate(JaxWsServiceFactoryBean.java:199) ~[cxf-rt-frontend-jaxws-3.2.1.jar:3.2.1]
at f.ateEndpoint(AbstractWSDLBasedEndpointFactory.java:103) ~[cxf-rt-frontend-simple-3.2.1. at f.ate(ServerFactoryBean.java:168) ~[cxf-rt-frontend-simple-3.2.1.jar:3.2.1]
at f.ate(JaxWsServerFactoryBean.java:211) ~[cxf-rt-frontend-jaxws-3.2.1.jar:3.2.1]
at f.Server(EndpointImpl.java:460) ~[cxf-rt-frontend-jaxws-3.2.1.jar:3.2.1]
at f.jaxws.EndpointImpl.doPublish(EndpointImpl.java:338) ~[cxf-rt-frontend-jaxws-3.2.1.jar:3.2.1]
... 31 common frames omitted
Caused by: l.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
at l.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91) ~[na:1.8.0_152]
at l.internal.bind.v2.TypeInfoSet(JAXBContextImpl.java:445) ~[na:1.8.0_152]
at l.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277) ~[na:1.
8.0_152]
at l.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:124) ~[na:1.8.0_152]
at l.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1123) ~[na:1.8.0_152]
at l.internal.bind.ateContext(ContextFactory.java:147) ~[na:1.8.0_152]
flect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_152]
flect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_152]
调用webservice服务flect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_152]
at flect.Method.invoke(Method.java:498) ~[na:1.8.0_152]
l.wInstance(ContextFinder.java:247) ~[na:1.8.0_152]
l.wInstance(ContextFinder.java:234) ~[na:1.8.0_152]
l.bind.ContextFinder.find(ContextFinder.java:462) ~[na:1.8.0_152]
l.wInstance(JAXBContext.java:641) ~[na:1.8.0_152]
at fmon.ateContext(JAXBContextCache.java:358) ~[cxf-core-3.2.1.jar:3.2.1]
at fmon.CachedContextAndSchemas(JAXBContextCache.java:246) ~[cxf-core-3.2.1.jar:3.2.1]
at f.ateJAXBContextAndSchemas(JAXBDataBinding.java:472) ~[cxf-rt-databinding-jaxb-3.2.1.jar:3.2.1]
at f.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:327) ~[cxf-rt-databinding-jaxb-3.2.1.jar:3.2.1]
... 42 common frames omitted
形成异常跟踪 :
Caused by: l.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
解决⽅法:(可能原因)
1. 将服务端的services接⼝返回的Map/List类型的值,改成基本类型或者string类型.因为在做webServices复杂类型值传递时,返回值
的类型不要⽤接⼝类型。对于处理复杂类型webservice有点出⼊。
2. 版本冲突,理论上来讲
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论