Skip to content

Instantly share code, notes, and snippets.

@vmarcinko
Created April 28, 2015 06:21
Show Gist options
  • Save vmarcinko/f514a6f6c26dbdf876b6 to your computer and use it in GitHub Desktop.
Save vmarcinko/f514a6f6c26dbdf876b6 to your computer and use it in GitHub Desktop.
Undertow-Spring MVC integration
package vmarcinko.undertow;
import io.undertow.Handlers;
import io.undertow.Undertow;
import io.undertow.server.HttpHandler;
import io.undertow.server.handlers.PathHandler;
import io.undertow.server.handlers.RedirectHandler;
import io.undertow.server.handlers.resource.FileResourceManager;
import io.undertow.servlet.Servlets;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.api.DeploymentManager;
import io.undertow.servlet.api.InstanceFactory;
import io.undertow.servlet.api.ServletContainerInitializerInfo;
import io.undertow.servlet.handlers.DefaultServlet;
import io.undertow.servlet.util.ImmediateInstanceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import vmarcinko.web.admin.WebAppServletContainerInitializer;
import javax.servlet.ServletContainerInitializer;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
public class UndertowServer implements InitializingBean, DisposableBean {
private final Logger logger = LoggerFactory.getLogger(UndertowServer.class);
private String webAppName;
private Resource webAppRoot;
private int port = 8080;
private ServletContainerInitializer servletContainerInitializer;
private Undertow server;
private DeploymentManager manager;
@Override
public void afterPropertiesSet() throws Exception {
logger.info("Starting Undertow web server on port {}, serving web application '{}' having root at {}", port, webAppName, webAppRoot.getFile().getAbsolutePath());
InstanceFactory<? extends ServletContainerInitializer> instanceFactory = new ImmediateInstanceFactory<>(servletContainerInitializer);
ServletContainerInitializerInfo sciInfo = new ServletContainerInitializerInfo(WebAppServletContainerInitializer.class, instanceFactory, new HashSet<>());
DeploymentInfo deploymentInfo = constructDeploymentInfo(sciInfo);
manager = Servlets.defaultContainer().addDeployment(deploymentInfo);
manager.deploy();
HttpHandler httpHandler = manager.start();
PathHandler pathHandler = constructPathHandler(httpHandler);
server = Undertow.builder()
.addHttpListener(port, "localhost")
.setHandler(pathHandler)
.build();
server.start();
logger.info("Undertow web server started; web application available at http://localhost:{}/{}", port, webAppName);
}
private DeploymentInfo constructDeploymentInfo(ServletContainerInitializerInfo sciInfo) throws IOException {
File webAppRootFile = webAppRoot.getFile();
return Servlets.deployment()
.addServletContainerInitalizer(sciInfo)
.setClassLoader(UndertowServer.class.getClassLoader())
.setContextPath(webAppName)
.setDeploymentName(webAppName + "-war")
.setResourceManager(new FileResourceManager(webAppRootFile, 0))
.addServlet(Servlets.servlet("default", DefaultServlet.class));
}
private PathHandler constructPathHandler(HttpHandler httpHandler) {
RedirectHandler defaultHandler = Handlers.redirect("/" + webAppName);
PathHandler pathHandler = Handlers.path(defaultHandler);
pathHandler.addPrefixPath("/" + webAppName, httpHandler);
return pathHandler;
}
@Override
public void destroy() throws Exception {
logger.info("Stopping Undertow web server on port " + port);
server.stop();
manager.stop();
manager.undeploy();
logger.info("Undertow web server on port " + port + " stopped");
}
public void setWebAppRoot(Resource webAppRoot) {
this.webAppRoot = webAppRoot;
}
public void setWebAppName(String webAppName) {
this.webAppName = webAppName;
}
public void setPort(int port) {
this.port = port;
}
public void setServletContainerInitializer(ServletContainerInitializer servletContainerInitializer) {
this.servletContainerInitializer = servletContainerInitializer;
}
}
package vmarcinko.web.admin;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.*;
import java.util.EnumSet;
import java.util.Set;
public class WebAppServletContainerInitializer implements ServletContainerInitializer, ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
XmlWebApplicationContext rootWebAppContext = new XmlWebApplicationContext();
rootWebAppContext.setConfigLocation("/WEB-INF/applicationContext.xml");
rootWebAppContext.setParent(applicationContext);
ctx.addListener(new ContextLoaderListener(rootWebAppContext));
FilterRegistration.Dynamic encodingFilter = ctx.addFilter("encoding-filter", CharacterEncodingFilter.class);
encodingFilter.setInitParameter("encoding", "UTF-8");
encodingFilter.setInitParameter("forceEncoding", "true");
encodingFilter.addMappingForServletNames(EnumSet.allOf(DispatcherType.class), false, "admin");
FilterRegistration.Dynamic springSecurityFilterChain = ctx.addFilter("springSecurityFilterChain", DelegatingFilterProxy.class);
springSecurityFilterChain.addMappingForServletNames(EnumSet.allOf(DispatcherType.class), false, "admin");
ServletRegistration.Dynamic dispatcher = ctx.addServlet("admin", DispatcherServlet.class);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/admin/*");
ServletRegistration.Dynamic dispatcher2 = ctx.addServlet("customer", DispatcherServlet.class);
dispatcher2.setLoadOnStartup(1);
dispatcher2.addMapping("/customer/*");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
@devcdcc
Copy link

devcdcc commented Jan 18, 2016

thanks by this, i believe this will run with out problem :)

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