Spring Tomcat 下的 CXF Soap Web 服务:未找到服务
Spring CXF Soap Web Service Under Tomcat: No Services Found
我正在尝试使用 CXF 和 Spring:
在 Tomcat 上设置一个简单的 CXF Web 服务 运行
我有一个 bootstrap CXF servlet 的 Web 应用程序初始化程序:
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected void registerContextLoaderListener(ServletContext servletContext)
{
CXFServlet cxfServlet = new CXFServlet();
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("cxf", cxfServlet);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/services/*");
}
.....
}
我有一个 Spring 配置 class:
@Configuration
public class WebServiceConfiguration
{
@Bean
public Endpoint endPoint()
{
EndpointImpl endpoint = new EndpointImpl(cxf(), eorthoWebService());
endpoint.getHandlers().add(inboundRequestHandler());
endpoint.getHandlers().add(outboundRequestHandler());
//the below works and uses cxf's embedded Jetty server
//endpoint.publish("http://localhost:9090/services/EorthoWebService");
//this doesn't work
endpoint.publish("/EorthoWebService");
return endpoint;
}
@Bean
public SpringBus cxf()
{
return new SpringBus();
}
@Bean
public EorthoWebService eorthoWebService()
{
return new EorthoWebServiceImpl();
}
}
我有一个 Web 服务实现:
@WebService(endpointInterface = "com.aoa.eortho.ws.service.EorthoWebService")
@SchemaValidation(type = SchemaValidationType.IN)
public class EorthoWebServiceImpl implements EorthoWebService {
@WebMethod
public RulesEngineOrthodonticSubmissionResponseEnv processRequest(RulesEngineOrthodonticSubmissionRequestEnv requestEnvelope) {
...
}
}
当我点击 /services 时,我得到了输出:
No services have been found.
我让它工作的唯一方法是如下发布,这似乎是将它发布到嵌入式 Jetty 服务器,而不是它部署到的 Tomcat 实例:
endpoint.publish("http://localhost:9090/services/EorthoWebService");
我错过了什么才能让它在 Tomcat 上运行:
endpoint.publish("/EorthoWebService");
您缺少的部分是 spring 上下文扫描。
来自Baeldung -- A Guide to Apache CXF with Spring
First, a Spring application context is created and configured to register a class containing configuration metadata:
AnnotationConfigWebApplicationContext context
= new AnnotationConfigWebApplicationContext();
context.register(ServiceConfiguration.class);
The ServiceConfiguration class is annotated with the @Configuration annotation to provide bean definitions. This class is discussed in the next subsection.
The following snippet shows how the Spring application context is added to the servlet context:
container.addListener(new ContextLoaderListener(context));
所以,完整的 class 是:
public class AppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(ServiceConfiguration.class);
container.addListener(new ContextLoaderListener(context));
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new CXFServlet());
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/services/*");
}
}
这与您的 AbstractAnnotationConfigDispatcherServletInitializer
扩展 class 不同,但是当我覆盖 onStartup
而不是 registerContextLoaderListener
时,它似乎也能正常工作。希望这足以让你理清头绪。
另外,我的配置class:
@Configuration
public class ServiceConfiguration {
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(cxf(), new HelloWorldImpl());
endpoint.publish("/HelloWorld");
return endpoint;
}
@Bean
public SpringBus cxf() {
return new SpringBus();
}
}
我正在尝试使用 CXF 和 Spring:
在 Tomcat 上设置一个简单的 CXF Web 服务 运行我有一个 bootstrap CXF servlet 的 Web 应用程序初始化程序:
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected void registerContextLoaderListener(ServletContext servletContext)
{
CXFServlet cxfServlet = new CXFServlet();
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("cxf", cxfServlet);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/services/*");
}
.....
}
我有一个 Spring 配置 class:
@Configuration
public class WebServiceConfiguration
{
@Bean
public Endpoint endPoint()
{
EndpointImpl endpoint = new EndpointImpl(cxf(), eorthoWebService());
endpoint.getHandlers().add(inboundRequestHandler());
endpoint.getHandlers().add(outboundRequestHandler());
//the below works and uses cxf's embedded Jetty server
//endpoint.publish("http://localhost:9090/services/EorthoWebService");
//this doesn't work
endpoint.publish("/EorthoWebService");
return endpoint;
}
@Bean
public SpringBus cxf()
{
return new SpringBus();
}
@Bean
public EorthoWebService eorthoWebService()
{
return new EorthoWebServiceImpl();
}
}
我有一个 Web 服务实现:
@WebService(endpointInterface = "com.aoa.eortho.ws.service.EorthoWebService")
@SchemaValidation(type = SchemaValidationType.IN)
public class EorthoWebServiceImpl implements EorthoWebService {
@WebMethod
public RulesEngineOrthodonticSubmissionResponseEnv processRequest(RulesEngineOrthodonticSubmissionRequestEnv requestEnvelope) {
...
}
}
当我点击 /services 时,我得到了输出:
No services have been found.
我让它工作的唯一方法是如下发布,这似乎是将它发布到嵌入式 Jetty 服务器,而不是它部署到的 Tomcat 实例:
endpoint.publish("http://localhost:9090/services/EorthoWebService");
我错过了什么才能让它在 Tomcat 上运行:
endpoint.publish("/EorthoWebService");
您缺少的部分是 spring 上下文扫描。
来自Baeldung -- A Guide to Apache CXF with Spring
First, a Spring application context is created and configured to register a class containing configuration metadata:
AnnotationConfigWebApplicationContext context
= new AnnotationConfigWebApplicationContext();
context.register(ServiceConfiguration.class);
The ServiceConfiguration class is annotated with the @Configuration annotation to provide bean definitions. This class is discussed in the next subsection. The following snippet shows how the Spring application context is added to the servlet context:
container.addListener(new ContextLoaderListener(context));
所以,完整的 class 是:
public class AppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(ServiceConfiguration.class);
container.addListener(new ContextLoaderListener(context));
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new CXFServlet());
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/services/*");
}
}
这与您的 AbstractAnnotationConfigDispatcherServletInitializer
扩展 class 不同,但是当我覆盖 onStartup
而不是 registerContextLoaderListener
时,它似乎也能正常工作。希望这足以让你理清头绪。
另外,我的配置class:
@Configuration
public class ServiceConfiguration {
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(cxf(), new HelloWorldImpl());
endpoint.publish("/HelloWorld");
return endpoint;
}
@Bean
public SpringBus cxf() {
return new SpringBus();
}
}