Ответ 1
Все, что нужно, - это вызов endpoint.publish()
выше.
Попытка развернуть конечную точку JAX-WS с помощью плагина Tomcat 7 Maven и CXF
2.7.8. В качестве предпочтения я не хочу иметь какой-либо XML-конфигурации для
Spring или CXF. Я вижу несколько блогов, статей, сообщений, используя cxf-servlet.xml
и CXFServlet, но ни один из них полностью не использует конфигурацию Java. Заглядывая в исходный код CXFServlet, он ищет cxf-servlet.xml
или что-то в контексте сервлета под ключом 'config-location'
. Я попытался программно зарегистрировать конечную точку вместо cxf-servlet.xml
, но она не работает; Я получаю 404 при доступе к службе. Любые идеи?
@Configuration
@ImportResource({ "classpath:META-INF/cxf/cxf.xml" })
public class CXFConfig {
@Autowired
Bus cxfBus;
// More code
@Bean
public Endpoint calculator() {
EndpointImpl endpoint = new EndpointImpl(cxfBus, new Calculator());
endpoint.setAddress("/CalculatorService");
return endpoint;
}
}
Все, что нужно, - это вызов endpoint.publish()
выше.
Все размещенные здесь данные не содержат 100% -ной конфигурации XML - все сообщения используют путь к классам: META-INF/cxf/cxf.xml, который также используется в большинстве руководств в Интернете. Но есть решение для этого: Определите org.apache.cxf.bus.spring.SpringBus как @ Bean и настройте name = Bus.DEFAULT_BUS_ID, исходя из org.apache.cxf.Bus.
Как описано в других ответах, необходимо создать экземпляр org.apache.cxf.jaxws.EndpointImpl - включая перенаправление Beans SpringBus и SEI-реализующего класса. Кроме того, следует публиковать публикацию() - Method of EndpointImpl, включая строку, содержащую конец URL:
package de.jonashackt.tutorial.configuration;
import javax.xml.ws.Endpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import de.codecentric.namespace.weatherservice.WeatherService;
import de.jonashackt.tutorial.endpoint.WeatherServiceEndpoint;
@Configuration
public class WebServiceConfiguration {
@Bean
public ServletRegistrationBean dispatcherServlet() {
return new ServletRegistrationBean(new CXFServlet(), "/soap-api/*");
}
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
@Bean
public WeatherService weatherService() {
return new WeatherServiceEndpoint();
}
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), weatherService());
endpoint.publish("/WeatherSoapService");
return endpoint;
}
}
Если вы хотите узнать больше об Apache CXF вместе с SpringBoot, я рекомендую посмотреть этот проект github.
Этот поток определенно поставил меня на правильный путь, чтобы заставить CXF работать в чистой конфигурации Spring Java, но он не предоставил все, что требуется.
Для себя, чистая конфигурация Java означает без файла web.xml
, который, как я думаю, предполагает этот ответ. Spring Загрузка, например, не использует файл web.xml
.
Итак, чтобы зарегистрировать конечную точку CXF без использования каких-либо файлов XML, вам понадобится файл конфигурации, который также загружает CXFServlet
.
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import javax.xml.ws.Endpoint;
@Configuration
@ImportResource({"classpath:META-INF/cxf/cxf.xml"})
public class JavaConfiguration {
@Autowired
private Bus bus;
@Bean
public Endpoint myServiceEndpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, new MyService());
endpoint.publish("/myservice");
return endpoint;
}
@Bean
public ServletRegistrationBean cxfServlet() {
ServletRegistrationBean servlet = new ServletRegistrationBean(new CXFServlet(), "/services/*");
servlet.setLoadOnStartup(1);
return servlet;
}
}
Вышеупомянутая конфигурация необходима для успешной загрузки конечной точки CXF в Spring.
Я также создал небольшой проект, который демонстрирует это.
Я верю, что если вы передадите свой beans внутри factory.setServiceBeans, он будет работать
package br.com.app.spring;
import java.util.Arrays;
import javax.ws.rs.ext.RuntimeDelegate;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import br.com.app.JaxRsApiApplication;
import br.com.app.services.EditionRest;
import br.com.app.services.EditionService;
@Configuration
@ImportResource(
{
"classpath:META-INF/cxf/cxf.xml",
"classpath:META-INF/cxf/cxf-extension-xml.xml",
"classpath:META-INF/cxf/cxf-servlet.xml"
})
public class CXFConfig {
@Bean(destroyMethod = "shutdown")
public SpringBus cxf() {
return new SpringBus();
}
@Bean
public EditionService editionRest() {
return new EditionRest();
}
@Bean
public JaxRsApiApplication jaxRsApiApplication() {
return new JaxRsApiApplication();
}
@Autowired
@Bean
public Server jaxRsServer(JacksonJsonProvider provider) {
JAXRSServerFactoryBean factory = RuntimeDelegate.getInstance().createEndpoint(jaxRsApiApplication(), JAXRSServerFactoryBean.class);
factory.setServiceBeans(Arrays.<Object> asList(editionRest()));
factory.setProviders(Arrays.<Object> asList(provider));
return factory.create();
}
@Bean
public JacksonJsonProvider jsonProvider() {
return new JacksonJsonProvider();
}
}
Если вы используете Spring Boot, вы можете использовать:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>${cxf.version}</version> <!-- 3.1.7 or higher -->
</dependency>
Чтобы добавить конечную точку:
import javax.xml.ws.Endpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebServiceConfig {
@Bean
public Endpoint endpoint(Bus cxfBus) {
EndpointImpl endpoint = new EndpointImpl(cxfBus, new Calculator());
endpoint.publish("/CalculatorService");
return endpoint;
}
}