package com.jetty.example; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.servlet.DispatcherType; import javax.servlet.http.HttpServlet; import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.ErrorHandler; import org.eclipse.jetty.server.handler.gzip.GzipHandler; import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler; /** * <pre> * 樣例: * JettyServer server = new JettyServer("demo"); * server.addHttpServlet("", "/h1", new HelloServlet("h1")); * server.addHttpServlet("", "/h2", new HelloServlet("h2")); * server.addFilter("com.jetty.example.MyFilter", null); * server.start("127.0.0.1", 8080); * server.awaitUninterruptibly(); * * </pre> * * Created by 黃坤平 on 2018/1/20. */ public class JettyServer { private String serverName; private Server server; private QueuedThreadPool pool; private ScheduledExecutorScheduler serverExecutor; private volatile boolean running = false; private List<ServletContextHandler> handlers = new ArrayList<ServletContextHandler>(); private List<FilterHolder> filters = new ArrayList<FilterHolder>(); public JettyServer(String serverName) throws Exception { this.serverName = serverName; pool = new QueuedThreadPool(); if (serverName == null) { serverName = ""; } if (!serverName.isEmpty()) { pool.setName(serverName); } pool.setDaemon(true); server = new Server(pool); ErrorHandler errorHandler = new ErrorHandler(); errorHandler.setShowStacks(true); errorHandler.setServer(server); server.addBean(errorHandler); serverExecutor = new ScheduledExecutorScheduler(serverName + "-JettyScheduler", true); } public void start(String hostName, int port) throws Exception { start(hostName, port, null); } public void start(String hostName, int port, String[] virtualHosts) throws Exception { for (FilterHolder filter : filters) { EnumSet<DispatcherType> enumDispatcher = EnumSet.of(DispatcherType.ASYNC, DispatcherType.ERROR, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST); for (ServletContextHandler handler: handlers) { handler.addFilter(filter, "/*", enumDispatcher); } } ContextHandlerCollection collection = new ContextHandlerCollection(); server.setHandler(collection); try { server.start(); int minThreads = 1; ServerConnector connector = newConnector(server, serverExecutor, new ConnectionFactory[]{ new HttpConnectionFactory()}, hostName, port); connector.setName(serverName); minThreads += connector.getAcceptors() * 2; server.addConnector(connector); for (ServletContextHandler handler : handlers) { if (virtualHosts != null) { handler.setVirtualHosts(virtualHosts); } GzipHandler gzipHandler = new GzipHandler(); gzipHandler.setHandler(handler); collection.addHandler(gzipHandler); gzipHandler.start(); } pool.setMaxThreads(Math.max(pool.getMaxThreads(), minThreads)); running = true; } catch (Exception e) { server.stop(); if (serverExecutor.isStarted()) { serverExecutor.stop(); } if (pool.isStarted()) { pool.stop(); } throw e; } } public void awaitUninterruptibly() throws InterruptedException { server.join(); } public void stop() throws Exception { if(!running) { return; } server.stop(); if (serverExecutor.isStarted()) { serverExecutor.stop(); } if (pool.isStarted()) { pool.stop(); } } public void addHttpServlet(String basePath, String path, HttpServlet servlet) { ServletContextHandler handler = createServletHandler(basePath, path, servlet); handlers.add(handler); } private ServletContextHandler createServletHandler(String basePath, String path, HttpServlet servlet) { String prefixedPath = ""; if("".equals(basePath) && "/".equals(path)) { prefixedPath = path; } else { prefixedPath = basePath + path; } ServletContextHandler contextHandler = new ServletContextHandler(); ServletHolder holder = new ServletHolder(servlet); contextHandler.setContextPath(prefixedPath); contextHandler.addServlet(holder, "/"); return contextHandler; } public void addFilter(String filterClassName, Map<String, Object> params) { FilterHolder holder = new FilterHolder(); holder.setClassName(filterClassName); if (params != null && !params.isEmpty()) { for (Entry<String, Object> entry : params.entrySet()) { holder.setInitParameter(entry.getKey(), entry.getValue().toString()); } } filters.add(holder); } private ServerConnector newConnector(Server server, ScheduledExecutorScheduler serverExecutor, ConnectionFactory[] connectionFactories, String hostName, int port) throws Exception { ServerConnector connector = new ServerConnector( server, null, serverExecutor, null, -1, -1, connectionFactories); connector.setPort(port); connector.start(); connector.setAcceptQueueSize(Math.min(connector.getAcceptors(), 8)); connector.setHost(hostName); return connector; } }
pom.xmljava
<jetty.version>9.3.20.v20170531</jetty.version> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-http</artifactId> <version>${jetty.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-continuation</artifactId> <version>${jetty.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-servlet</artifactId> <version>${jetty.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-servlets</artifactId> <version>${jetty.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-proxy</artifactId> <version>${jetty.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-client</artifactId> <version>${jetty.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-util</artifactId> <version>${jetty.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-security</artifactId> <version>${jetty.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-plus</artifactId> <version>${jetty.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> <version>${jetty.version}</version> <scope>provided</scope> </dependency>