title: How to serve index.html with embedded jetty?
body: <p>I have created the embedded jetty server below. It successfully servers my REST API from [host]:[port]:/api/</p>
  
  <p>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!</p>
  
  <p>public class JettyServer {</p>
  
  <pre><code>  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);
    }
  }
  </code></pre>