Drew
Drew

Reputation: 57

How to serve index.html with embedded jetty?

I have created the embedded jetty server below. It successfully servers my REST API from [host]:[port]:/api/

I now have an Angular app that I want to serve in addition to the API, how do I update my code so that the server serves the app's index.html file? After trying several different aproaches, I find that my understanding is lacking I'm not able to adapt the examples I have seen. Any suggestions or input would be gratefully received. Thanks!

public class JettyServer {

  private static final String API_PREFIX = "/api/*";
  private static final String RESOURCE_PACKAGES_TO_SCAN = "org.brewtraption.rest";
  Logger logger = LoggerFactory.getLogger(JettyServer.class);
  private JettyServerConfig config = null;

  public JettyServer(final JettyServerConfig config) {
    this.config = config;
  }

  public void start() {
    InetSocketAddress socket = new InetSocketAddress(config.getHost(), config.getPort());
    Server server = new Server(socket);
    ServletHolder servletHolder = configureAPIResources();

    ServletContextHandler context = configureServletContextHandler(server, servletHolder);
    initaliseWebSocketContainer(context);

    startBrewtraptionServer(server);
  }

  private void startBrewtraptionServer(Server server) {
    try {
      server.start();
      server.join();
    } catch (Exception e) {
      String message = "Unable to start Brewtraption Server. %s %s";
      logger.error(String.format(message, e.getClass().getName(), e.getMessage()));
    }
  }

  private void initaliseWebSocketContainer(ServletContextHandler context) {
    try {
      ServerContainer container = WebSocketServerContainerInitializer.configureContext(context);
      container.addEndpoint(EventSocket.class);
    } catch (ServletException | DeploymentException e) {
      String message = "Unable to create ServerContainer. %s %s";
      logger.error(String.format(message, e.getClass().getName(), e.getMessage()));
    }
  }

  private ServletContextHandler configureServletContextHandler(Server server, ServletHolder servletHolder) {
    ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
    context.setContextPath("/");
    context.addServlet(servletHolder, API_PREFIX);

    FilterHolder filterHolder = new FilterHolder(CrossOriginFilter.class);
    filterHolder.setInitParameter("allowedOrigins", "*");
    filterHolder.setInitParameter("allowedMethods", "GET, POST, PUT");
    context.addFilter(filterHolder, "/*", null);

    server.setHandler(context);
    return context;
  }

  private ServletHolder configureAPIResources() {
    ResourceConfig resourceConfig = new ResourceConfig();
    resourceConfig = resourceConfig.packages(RESOURCE_PACKAGES_TO_SCAN)
      .register(JacksonFeature.class);
    ServletContainer servletContainer = new ServletContainer(resourceConfig);
    return new ServletHolder(servletContainer);
  }
}

Upvotes: 3

Views: 3384

Answers (1)

Joakim Erdfelt
Joakim Erdfelt

Reputation: 49462

You need 2 things.

  1. A DefaultServlet
  2. A configured welcome files.
    context.setWelcomeFiles(new String[] { "index.html", "index.htm", "index.jsp" });

    // Lastly, the default servlet for root content (always needed, to satisfy servlet spec)
    // It is important that this is last.
    ServletHolder holderPwd = new ServletHolder("default", DefaultServlet.class);
    holderPwd.setInitParameter("resourceBase",pwdPath);
    holderPwd.setInitParameter("dirAllowed","true");
    context.addServlet(holderPwd,"/");

Upvotes: 3

Related Questions