我试图在同一个应用程序中实现spring rest和soap。我为REST和SOAP配置了两个单独的配置。但我无法启动服务器因为我得到了以下异常 “无法启动组件[StandardEngine [Catalina] .StandardHost [localhost] .StandardContext”。 帮我在java config中定义两个调度程序servlet。
我的课程:
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
答案 0 :(得分:1)
此处的问题出在您的配置yourConfig extends AbstractAnnotationConfigDispatcherServletInitializer
类中。
您可以在Web根路径下映射两个配置getServletMappings。
更好的方法是为你的rest api设置一个getServletMappings路径,为ws api设置另一个路径,如果需要,为另一个提供页面服务,如下所示:
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,则应使用内置的,不要配置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启动 我希望这可以帮到你