Skip to content

Instantly share code, notes, and snippets.

@vegaasen
Last active February 24, 2022 17:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vegaasen/76be99148ecfc8473875 to your computer and use it in GitHub Desktop.
Save vegaasen/76be99148ecfc8473875 to your computer and use it in GitHub Desktop.
Simple example on how to get CXF to work with Jetty and stuff

CXF Standalone

Introduction

This is a simple example on how to get Jetty & CXF to play along with an embedded mind. Quite simple example :-). Please note that all of the stuff here is an excertp :-).

Maven configration

  <dependencies>
        <!--DIFI-->
        <dependency>
            <groupId>no.difi.vefa</groupId>
            <artifactId>validate-lib</artifactId>
            <version>1.0.0</version>
        </dependency>
        <!--JETTY-->
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>${server.jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>${server.jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-io</artifactId>
            <version>${server.jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-util</artifactId>
            <version>${server.jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>${server.jetty.version}</version>
        </dependency>
        <!--SERVLET-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${server.javax.servlet-api.version}</version>
        </dependency>
        <!--CXF-->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.5.RELEASE</version>
        </dependency>
    </dependencies>
    
        <build>
        <plugins>
            <plugin>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <createDependencyReducedPom>true</createDependencyReducedPom>
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                    <transformers>
                        <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                        <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>com.vegaasen.web.run.StartApplication</mainClass>
                            <manifestEntries>
                                <Specification-Version>${project.parent.version}</Specification-Version>
                                <Specification-Title>${name}</Specification-Title>
                                <Specification-Vendor>${manifest.spec-vendor}</Specification-Vendor>
                            </manifestEntries>
                        </transformer>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                            <resource>META-INF/cxf/bus-extensions.txt</resource>
                        </transformer>
                    </transformers>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Java: Web Service setup

The abstract service

package no.difi.vefa.soap.ws.abs;

/**
 * _what_
 *
 * @author <a href="mailto:???">vegaraa</a>
 */
public abstract class AbstractWebService {
}

The service

  package no.difi.vefa.soap.ws;
  
  import no.difi.vefa.message.Messages;
  import no.difi.vefa.soap.common.WebServiceAttributes;
  import no.difi.vefa.soap.ws.abs.AbstractWebService;
  
  import javax.jws.WebMethod;
  import javax.jws.WebParam;
  import javax.jws.WebResult;
  import javax.jws.WebService;
  import javax.jws.soap.SOAPBinding;
  import javax.xml.bind.annotation.XmlElement;
  
  /**
   * ..what..
   *
   * @author <a href="mailto:vegaasen@gmail.com">vegaasen</a>
   */
  @WebService(targetNamespace = WebServiceAttributes.NAMESPACE, name = WebServiceAttributes.Services.VALIDATION)
  @SOAPBinding(
          style = SOAPBinding.Style.DOCUMENT,
          use = SOAPBinding.Use.LITERAL,
          parameterStyle = SOAPBinding.ParameterStyle.WRAPPED
  )
  public class ValidationService extends AbstractWebService {
  
      @WebMethod(operationName = "validateInvoiceRequest")
      @WebResult(
              name = "validateInvoiceResponse",
              targetNamespace = WebServiceAttributes.NAMESPACE
      )
      public Messages validateInvoice(
              @WebParam(name = "invoice",
                      mode = WebParam.Mode.IN,
                      targetNamespace = WebServiceAttributes.NAMESPACE
              ) @XmlElement(required = true) final String invoice) {
          System.out.println("Heisann");
          return null;
      }
  }

Jetty controller:

  package no.difi.vefa.soap.run.container;
  
  import com.sun.jersey.spi.container.servlet.ServletContainer;
  import no.difi.vefa.soap.ws.ValidationService;
  import no.difi.vefa.soap.ws.abs.AbstractWebService;
  import org.apache.cxf.Bus;
  import org.apache.cxf.BusFactory;
  import org.apache.cxf.bus.CXFBusFactory;
  import org.apache.cxf.transport.servlet.CXFServlet;
  import org.eclipse.jetty.server.Connector;
  import org.eclipse.jetty.server.Server;
  import org.eclipse.jetty.server.ServerConnector;
  import org.eclipse.jetty.server.session.SessionHandler;
  import org.eclipse.jetty.servlet.ServletContextHandler;
  import org.eclipse.jetty.servlet.ServletHolder;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  import javax.xml.ws.Endpoint;
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * This controls the application server itself. It exposes two key methods ; stop() + start().
   *
   * @author <a href="????">vegaraa</a>
   */
  public enum JettyContainer {
  
      INSTANCE;
  
      private static final Logger LOG = LoggerFactory.getLogger(JettyContainer.class);
      private static final String SLASH = "/";
      private static final String CONTEXT_PATH = SLASH;
      private static final String PATH_SPEC = "/*";
      private static final String ENDPOINT_URI = "iam", WEB_SERVICE_URI = "services";
      private static final String WS_PATH_SPEC = "/" + WEB_SERVICE_URI + "/*";
  
      private Server webServer;
      private Bus bus;
  
      public void start(int port) {
          try {
              if (port <= 0) {
                  port = ContainerDefaults.DEFAULT_PORT;
              }
              webServer = new Server();
              webServer.setConnectors(assembleConnectors(port, webServer));
              final ServletContextHandler applicationContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
              applicationContext.setContextPath(CONTEXT_PATH);
              applicationContext.setSessionHandler(new SessionHandler());
              configureCxf(applicationContext);
              webServer.setHandler(applicationContext);
              webServer.start();
              LOG.info(String.format("Server now running on http://localhost:%s", port));
              LOG.info(String.format("Access SOAP-services on http://localhost:%s/%s", port, WEB_SERVICE_URI));
              LOG.info(String.format("Access REST-services on anywhereBut(http://localhost:%s/%s/*)", port, WEB_SERVICE_URI));
          } catch (Exception e) {
              LOG.error("Unable to start webserver", e);
              stop();
              LOG.error("The webServer was not started.");
          }
      }
  
      public void stop() {
          if (webServer != null) {
              if (!webServer.isRunning()) {
                  return;
              }
              try {
                  while (!webServer.isStopped()) {
                      webServer.stop();
                  }
              } catch (Exception e) {
                  LOG.error("Unable to stop the running server.", e);
              }
          }
      }
  
      protected Connector[] assembleConnectors(final int port, final Server server) {
          if (port == 0) {
              throw new IllegalArgumentException("The arguments is null.");
          }
          final List<Connector> connectors = new ArrayList<>();
          final ServerConnector httpConnector = new ServerConnector(server);
          httpConnector.setPort(port);
          connectors.add(httpConnector);
          if (connectors.isEmpty()) {
              throw new RuntimeException("No controllers defined, even though they were expected to be.");
          }
          return connectors.toArray(new Connector[connectors.size()]);
      }
  
      protected void configureCxf(final ServletContextHandler applicationContext) {
          System.setProperty(BusFactory.BUS_FACTORY_PROPERTY_NAME, CXFBusFactory.class.getName());
          bus = BusFactory.getDefaultBus(true);
          final CXFServlet cxfServlet = new CXFServlet();
          cxfServlet.setBus(bus);
          final ServletHolder cxfServletHolder = new ServletHolder(cxfServlet);
          cxfServletHolder.setName(WEB_SERVICE_URI);
          cxfServletHolder.setForcedPath(WEB_SERVICE_URI);
          applicationContext.addServlet(cxfServletHolder, WS_PATH_SPEC);
          LOG.info("Found request listners. Adding to the context.");
          BusFactory.setDefaultBus(bus);
          initializeSoapServices();
      }
  
      private void initializeSoapServices() {
          final ValidationService kdaIamWebService = new ValidationService();
          publishService(kdaIamWebService);
      }
  
      private void publishService(final AbstractWebService service) {
          Endpoint.publish(String.format("%s%s", SLASH, ENDPOINT_URI), service);
      }
  
  }

Conclusion

It was quite easy :) Good luck!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment