【问题标题】:loading multiple beans in spring boot using soap web service使用soap web服务在spring boot中加载多个bean
【发布时间】:2025-12-18 10:25:01
【问题描述】:

我正在尝试使用 Spring Boot 编写肥皂网络服务。我有 2 个 xsd。 REL-6-MM7-1-4.xsd 依赖于 SoapEnvelope.xsd。

谁能帮我解决这个问题。

import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.ws.config.annotation.EnableWs;
import org.springframework.ws.config.annotation.WsConfigurerAdapter;
import org.springframework.ws.transport.http.MessageDispatcherServlet;
import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.xsd.SimpleXsdSchema;
import org.springframework.xml.xsd.XsdSchema;
import org.springframework.xml.xsd.XsdSchemaCollection;


@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
    @Bean
    public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);
        servlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean(servlet, "/ws/*");
    }

    @Bean(name = "REL-6-MM7-1-4")
    public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchemaCollection xsdSchemaCollection) {
        DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
        wsdl11Definition.setPortTypeName("MMSPort");
        wsdl11Definition.setLocationUri("/ws");
        wsdl11Definition.setTargetNamespace("http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-4");
        wsdl11Definition.setSchemaCollection(xsdSchemaCollection);
        return wsdl11Definition;
    }

    @Bean
    public XsdSchemaCollection getXsdCollection() {
        return new XsdSchemaCollection() {

            public XsdSchema[] getXsdSchemas() {
                return new XsdSchema[]{new SimpleXsdSchema(new ClassPathResource("REL-6-MM7-1-4.xsd")), new SimpleXsdSchema(new ClassPathResource("SoapEnvelope.xsd"))};
            }

            public XmlValidator createValidator() {
                throw new UnsupportedOperationException();
            }
        };
    }

我曾尝试公开 2 个 bean,但是当我启动应用程序时出现以下错误。

在类路径资源 [hello/WebServiceConfig.class] 中定义名称为“REL-6-MM7-1-4”的 bean 创建错误:调用 init 方法失败;嵌套异常是 java.lang.NullPointerException

【问题讨论】:

    标签: soap spring-boot wsdl


    【解决方案1】:

    尝试修改您的方法,如下所示它应该可以工作。

        @Bean
        public XsdSchema studentSchema() {
            return new SimpleXsdSchema(new ClassPathResource("school.xsd"));
        }
    
        @Bean
        public XsdSchema employeeSchema() {
            return new SimpleXsdSchema(new ClassPathResource("employee.xsd"));
        }     
    
    
         @Bean
            public XsdSchemaCollection getXsdCollection() {
    
            return  new XsdSchemaCollection() {
    
            @Override
            public XmlValidator createValidator() {
                // TODO Auto-generated method stub
                return null;
            }
    
            @Override
            public XsdSchema[] getXsdSchemas() {
                return new XsdSchema[]{studentSchema(),employeeSchema()}; 
            }};
    

    【讨论】:

      【解决方案2】:

      这是我所做的:

      wsdl11Definition.setSchemaCollection(updateXsds());
      ....
      @Bean
      public XsdSchemaCollection updateXsds() throws Exception {
      
          CommonsXsdSchemaCollection xsds = new CommonsXsdSchemaCollection(
              new ClassPathResource("xsd1.xsd"),
              new ClassPathResource("xsd2.xsd")
              );
      
          xsds.setUriResolver(new DefaultURIResolver());
          xsds.setInline(true);
          return xsds;
      }   
      

      【讨论】:

        【解决方案3】:

        如果您按照 their site 中的 spring 教程进行操作,那么您可以使用多个 @Bean 方法,但使用相同的 corespodent 名称。

        您需要为 MessageDispatcherServlet 和 DefaultWsdl11Definition 指定 bean 名称。 Bean 名称决定了 Web 服务和生成的 WSDL 文件可用的 URL。

        这样,你可以选择你想要的女巫。 它应该看起来像这样

        @Bean(name = "REL-6-MM7-1-4")
        public DefaultWsdl11Definition RELWsdl11Definition(XsdSchema schema) {
            DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
            wsdl11Definition.setSchema(schema);
            // omitted code... 
        }
        @Bean(name = "SoapEnvelope")
        public DefaultWsdl11Definition SoapEnvelopeWsdl11Definition(XsdSchema schema) {
            DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
            /// omitted code...     
        }
        
        @Bean
        public XsdSchema REL-6-MM7-1-4Schema() {
            return new SimpleXsdSchema(new ClassPathResource("REL-6-MM7-1-4.xsd"));
        }
        
        @Bean
        public XsdSchema SoapEnvelopeSchema() {
            return new SimpleXsdSchema(new ClassPathResource("SoapEnvelope.xsd"));
        }
        

        【讨论】: