【问题标题】:Expose Rest and Soap for one endpoint simultaneously by Spring and CXF通过 Spring 和 CXF 同时为一个端点公开 Rest 和 Soap
【发布时间】:2017-12-12 12:30:30
【问题描述】:

我有一个非常简单的服务,它必须以两种方式公开:REST 和 SOAP 我写了以下代码:

@WebService(name = "Base")
@Path("/Base")
@Produces("application/json")
public class BaseService
{
    @POST
    @Path("/Hello")
    public String sayHello()
    {
        return  "Hello";
    }
}

那是我的端点,我将其配置如下:

import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.ArrayList;

@Configuration
public class CxfConfiguration {
    @Bean( destroyMethod = "shutdown" )
    public SpringBus cxf() {
        return new SpringBus();
    }

    @Bean @DependsOn( "cxf" )
    public Server getServer() 
    {
        JaxWsServerFactoryBean wsFactory = new JaxWsServerFactoryBean();
        wsFactory.setServiceBean(getBaseService());
        return wsFactory.create();
    }

    @Bean(name = "RestWS") @DependsOn( "cxf" )
    public Server getServerRest()
    {
        JAXRSServerFactoryBean restFactory = new JAXRSServerFactoryBean();
        ArrayList<Object> objectArrayList = new ArrayList<>();
        restFactory.setServiceBean(getBaseService());
        restFactory.setProvider(new JacksonJsonProvider());

        return restFactory.create();
    }

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("facade.xml");

    @Bean
    public BaseService getBaseService()
    {
        return (BaseService)applicationContext.getBean("base_service");
    }
}

最后facade.xml 是:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="base_service" class="BaseService"/>

</beans>

当我运行我的应用程序时,我得到NullPointerException

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'RestWS' defined in CxfConfiguration: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.cxf.endpoint.Server]: Factory method 'getServerRest' threw exception; nested exception is org.apache.cxf.service.factory.ServiceConstructionException
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:583)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1249)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1098)

底线是我希望同时拥有这两种服务形式,但我遇到了上述异常。当我评论getServergetServerRest 方法之一时,一切都会好起来的。

【问题讨论】:

    标签: java spring rest soap cxf


    【解决方案1】:

    当您想在 SOAPREST 标准中表示服务时,您必须为 REST 定义一个服务器并为SOAP。 对于您的问题,您必须通过以下代码更改 CxfConfiguration 类:

    import org.apache.cxf.bus.spring.SpringBus;
    import org.apache.cxf.endpoint.Server;
    import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
    import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
    import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.DependsOn;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import java.util.ArrayList;
    
    @Configuration
    public class CxfConfiguration 
    {
        @Autowired
        private ApplicationContext applicationContext;
    
        @Bean( destroyMethod = "shutdown" )
        public SpringBus cxf() {
            return new SpringBus();
        }
    
        @Bean(name = "RestWS") 
        public Server getServerRest()
        {
            JAXRSServerFactoryBean restFactory = new JAXRSServerFactoryBean();
            ArrayList<Object> objectArrayList = new ArrayList<>();
            restFactory.setServiceBean(getBaseService());
            restFactory.setProvider(new JacksonJsonProvider());
    
            return restFactory.create();
        }
       @Bean 
        public Server getServer() 
        {
            Bus bus = (Bus) applicationContext.getBean(Bus.DEFAULT_BUS_ID);
            Object implementor = getBaseService();
            EndpointImpl endpoint = new EndpointImpl(bus, implementor);
            endpoint.publish("/Base");
            return endpoint ;
        }
    
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("facade.xml");
    
        @Bean
        public BaseService getBaseService()
        {
            return (BaseService)applicationContext.getBean("base_service");
        }
    }
    

    这可以解决您的问题,但我认为最好为每个 RESTSOAP 服务设置不同的路径或地址。

    【讨论】:

    • 当然我编辑了一些地方,例如应用程序上下文,因为它被复制了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 2015-05-03
    相关资源
    最近更新 更多