java - 一个 Web 应用程序中的 Spring MVC 和 Spring WS 调度程序 Servlet 配置

标签 java spring rest spring-mvc soap

我尝试在同一个应用程序中实现 Spring Rest 和 Soap。我为 REST 和 SOAP 配置了两个单独的配置。但是我无法启动服务器,因为我遇到了异常 “无法启动组件 [StandardEngine[Catalina].StandardHost[localhost].StandardContext”。 帮我在 java 配置中定义两个调度程序 servlet。

我的类(class):

REST API 配置:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.test.test1.*" })
public class RestConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(
            List<HttpMessageConverter<?>> converters) {
        converters.add(extendedJsonConvertor());
        super.configureMessageConverters(converters);
    }
    @Bean
    public MappingJackson2HttpMessageConverter extendedJsonConvertor() {
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();

        mappingJackson2HttpMessageConverter
                .setObjectMapper(getNullAndEmptyFilteredObjectMapper());
        return mappingJackson2HttpMessageConverter;
    }

    /**
     * Gets the null and empty filtered object mapper.
     *
     */
    @Bean
    public ObjectMapper getNullAndEmptyFilteredObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
       // objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);        
        DateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy hh:mm:ss");
        objectMapper.setDateFormat(dateFormat);
        return objectMapper;
    }



}

REST MVC 配置:

public class RESTMvcConfiguration extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[0];
    }

    @Override
    protected String getServletName() {
        return "REST";
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { RestConfiguration.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
}

SOAP 配置:

@EnableWs
@Configuration
@ComponentScan(basePackages = { "com.test.test1.*" })
public class SoapServiceConfiguration 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 = "country")
    public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) {
        DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
        wsdl11Definition.setPortTypeName("CountryPort");
        wsdl11Definition.setLocationUri("/ws");
        wsdl11Definition.setTargetNamespace("http://test.*.*.com");
        wsdl11Definition.setSchema(countriesSchema);
        return wsdl11Definition;
    }

    @Bean
    public XsdSchema countriesSchema() {
        return new SimpleXsdSchema(new ClassPathResource("country.xsd"));
    }
}

SOAP MVC 配置:

public class SoapMvcConfiguration extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[0];
    }

    @Override
    protected String getServletName() {
        return "SOAP";
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { SoapServiceConfiguration.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    }

异常

01:14:51.978 [localhost-startStop-1] DEBUG c.a.c.c.RESTMvcConfiguration - No ContextLoaderListener registered, as createRootApplicationContext() did not return an application context
01:14:52.104 [localhost-startStop-1] DEBUG c.a.c.s.c.SoapMvcConfiguration - No ContextLoaderListener registered, as createRootApplicationContext() did not return an application context
May 05, 2016 1:14:52 AM org.apache.catalina.core.ContainerBase startInternal
SEVERE: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/TEST]]
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:188)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1122)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:819)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1574)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1564)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/TEST]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
    ... 6 more
Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getVirtualServerName()Ljava/lang/String;
    at org.apache.tomcat.websocket.server.WsServerContainer.<init>(WsServerContainer.java:149)
    at org.apache.tomcat.websocket.server.WsSci.init(WsSci.java:131)
    at org.apache.tomcat.websocket.server.WsSci.onStartup(WsSci.java:47)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5580)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    ... 6 more

最佳答案

这里的问题出在您的配置 yourConfig 扩展 AbstractAnnotationConfigDispatcherServletInitializer 类中。

您将两个配置 getServletMappings 映射到 Web 根路径下。

更好的方法是为您的其余 api 提供一个 getServletMappings 路径,为 ws api 提供一个 getServletMappings 路径,如果需要,为页面服务提供另一个路径,如下所示:

    public class SoapMvcConfiguration extends
            AbstractAnnotationConfigMessageDispatcherServletInitializer{

        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class<?>[0];
        }

        @Override
        protected String getServletName() {
            return "soap";
        }

        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class<?>[] { SoapServiceConfiguration.class };
        }

        @Override
        protected String[] getServletMappings() {
            return new String[] { "/ws/*" };
        }
    }

    public class RestMvcConfiguration extends
            AbstractAnnotationConfigDispatcherServletInitializer {

        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class<?>[0];
        }

        @Override
        protected String getServletName() {
            return "rest";
        }

        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class<?>[] { RestConfiguration.class };
        }

        @Override
        protected String[] getServletMappings() {
            return new String[] { "/api/*" };
        }

    }

你不应该使用ServletRegistrationBean Bean,因为这个bean是用于Spring boot的。如果您使用 Boot,则应该使用内置的并且不要配置 AbstractAnnotationConfigMessageDispatcherServletInitializer。最好使用 Spring Boot 内置的 AbstractAnnotationConfigMessageDispatcherServletInitializer。

这是我的 SOAP 配置类:

@EnableWs
@Configuration
@ComponentScan(value = "com.ws")
public class SoapServiceConfiguration extends WsConfigurerAdapter {


    @Bean
    public DefaultWsdl11Definition country(XsdSchema countriesSchema) {
        DefaultWsdl11Definition definition = new DefaultWsdl11Definition();
        definition.setSchema(countriesSchema);

        definition.setPortTypeName("Country");
        definition.setLocationUri("http://wstest/uri");
        definition.setTargetNamespace("http://wstest");

        return definition;
    }

    @Bean
    public XsdSchema countriesSchema() {
        System.out.println("CONFIG");

        return new SimpleXsdSchema(new ClassPathResource("country.xsd"));
    }
}

这是我的 xsd:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://wstest"
           targetNamespace="http://wstest" elementFormDefault="qualified">

    <xs:element name="getCountryRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="getCountryResponse">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="country" type="tns:country"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:complexType name="country">
        <xs:sequence>
            <xs:element name="name" type="xs:string"/>
            <xs:element name="population" type="xs:string"/>
            <xs:element name="capital" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>

</xs:schema>

这是我的 pom:

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.springapp</groupId>
    <artifactId>untitled6</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>untitled6</name>

    <properties>
    </properties>

    <dependencies>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>

        <dependency>
            <groupId>wsdl4j</groupId>
            <artifactId>wsdl4j</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.ws</groupId>
            <artifactId>spring-ws-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.ws</groupId>
            <artifactId>spring-ws-support</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.spring.platform</groupId>
                <artifactId>platform-bom</artifactId>
                <version>2.0.3.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>

        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.5.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <version>2.2</version>
            <executions>
                <execution>
                    <id>xjc</id>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <sources>
                    <source>${project.basedir}/src/main/resources</source>
                </sources>
                <outputDirectory>${project.basedir}/src/main/java</outputDirectory>
                <clearOutputDir>false</clearOutputDir>
            </configuration>
        </plugin>
    </plugins>
</build>

</project>

在我的配置中我不使用 Spring boot 我希望这可以帮助你

关于java - 一个 Web 应用程序中的 Spring MVC 和 Spring WS 调度程序 Servlet 配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37035689/

相关文章:

spring - 将 jndi 数据源与 Spring Batch 管理一起使用

spring - 在命名空间内使用 Spring 配置文件

java - BIRT 报告生成 - 如何保留所有行数据?

swift - 发布图像对象 Clarifai Rest api swift

javascript - Outlook Rest Api — 获取特定时区的日历 View (REST)

java - Spring Boot 2 没有序列化 LocalDateTime

java - 何时有效地使用线程

java - 如何在运行时执行通过网络发送的 java 程序/文件

c++ - 从 Win32 C++ 程序上传文件到 OneDrive(SkyDrive)

java - 如何迭代由 GSON 生成的 JAVA 对象列表