I am new to Vaadin, just generated the application in Vaadin web site and built it locally. Then I added Apache CXF SOAP service to it, but I am unable to use the Tomcat that Vaadin is using, but instead I load SOAP in Jetty using:
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>${cxf.version}</version> <scope>compile</scope> </dependency>
My Vaadin application is:
@SpringBootApplication @Theme(value = "iciclient", variant = Lumo.DARK) @PWA(name = "ICI Client", shortName = "ICI Client", offlineResources = {"images/logo.png"}) public class Application extends SpringBootServletInitializer implements AppShellConfigurator { public static void main(String[] args) { LaunchUtil.launchBrowserInDevelopmentMode(SpringApplication.run(Application.class, args)); try { System.out.println("Starting IciEventClient"); Object implementor = new IciEventServiceSoap12Impl(); String address = "http://localhost:8081/ici/IciEventService"; Endpoint.publish(address, implementor); // http://localhost:8081/ici/IciEventService?WSDL } catch (Exception e) { e.printStackTrace(); } } }
While this works, I would like to get rid of separate Jetty dependency and run the SOAP service in Vaadin Tomcat (localhost:8080). Should be simple but I can’t figure out how to do it. I think that it needs a separate servlet and route, but I don’t know how to add them. There is no web.xml in the Vaadin application, for example.
Advertisement
Answer
I am not familiar with Apache CXF, but based on CXF docs and the sample project I think I got it to work.
I downloaded a new Vaadin 14/Java 8 project from start.vaadin.com, and did the following:
Added the dependency
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>3.4.3</version> </dependency>
Created a web service
import javax.jws.WebMethod; import javax.jws.WebService; @WebService public class Test { @WebMethod public String test() { return "This works"; } }
Exposed it as a bean in my
Application
classimport javax.xml.ws.Endpoint; import org.apache.cxf.Bus; import org.apache.cxf.jaxws.EndpointImpl; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.vaadin.artur.helpers.LaunchUtil; import org.vaadin.erik.endpoint.Test; @SpringBootApplication public class Application extends SpringBootServletInitializer { public static void main(String[] args) { LaunchUtil.launchBrowserInDevelopmentMode(SpringApplication.run(Application.class, args)); } @Bean public Endpoint test(Bus bus) { EndpointImpl endpoint = new EndpointImpl(bus, new Test()); endpoint.publish("/Test"); return endpoint; } }
That was it! At least I can now list the service definition at http://localhost:8080/services/Test?wsdl
The first documentation link lists some configurations you can do, for example to change the /services
path. The example project shows how to configure Spring actuator metrics if that is something you need.
You might want to create a separate @Configuration
-annotated class for all your service @Bean
definitions.
If you don’t want to use the starter dependency, this Baeldung article looks promising.