文档章节

基于jetty 自制Java Web Server 容器

张宋付
 张宋付
发布于 2010/04/13 14:25
字数 1121
阅读 3.2K
收藏 7

精选30+云产品,助力企业轻松上云!>>>

 

1.main class 如下;
public final class Bootstrap {
	//~ Static fields/initializers ============================================= 
	
	private static final String SHUTDOWN = "SHUTDOWN";
    private static final String RELOAD = "RELOAD";
	
	//~ Instance fields ========================================================

	private Logger logger;
	
	private Server server;
	
    /**
     * The port number on which we wait for shutdown commands.
     */
    private int port;

    /**
     * A random number generator that is only used if
     * the shutdown command string is longer than 1024 characters.
     */
    private Random random = null;
	
	//~ Constructors ===========================================================
	
	private Bootstrap() {
		
	}

	//~ Methods ================================================================
	
	private Logger getLogger() {
		if (logger == null) {
			logger = LoggerFactory.getLogger(getClass());
		}
		return logger;
	}
	
	public void init() {
		String painiuHome = System.getProperty("net365.home", System.getProperty("user.dir", "."));

		String configDir = System.getProperty("net365.config.dir");
		if (configDir == null) {
			configDir = painiuHome + File.separator + "etc" + File.separator;
		}
		if (!configDir.endsWith(File.separator)) {
			configDir += File.separator;
		}
		
		String configFile = configDir + "net365.properties";
		Map vars = new HashMap();
		vars.put("home", painiuHome);
		Configuration.initialize(configFile, vars);
		
		initLoggingSystem(configDir);
		
		port = Configuration.getInteger("server.shutdown.port", 8014);
	}
	
	private void initLoggingSystem(String configDir) {
		File loggingConfigFile = new File(configDir, "logging.properties");
		if (loggingConfigFile.exists()) {
			System.setProperty("java.util.logging.config.file", loggingConfigFile.getAbsolutePath());
		}
		File log4jConfigFile = new File(configDir, "log4j.properties");
		if (log4jConfigFile.exists()) {
			PropertyConfigurator.configure(log4jConfigFile.getAbsolutePath());
		}
	}
	
	public void startServer() throws Exception {
		getLogger().info("Bootstrap: Starting Server...");
		
		server = new Server();
		server.initialize();
		
		server.setGracefulShutdown(Configuration.getInteger("server.shutdown.timeout", 0));
		server.setStopAtShutdown(true);
		
		server.start();
	}
	
	public void stopServer() throws Exception {
		getLogger().info("Bootstrap: Stopping Server...");
		server.stop();
	}
	
	public static void main(String[] args) {
		Bootstrap bootstrap = new Bootstrap();
		
		try {
			bootstrap.init();
			
			String command = "start";
			if (args.length > 0) {
				command = args[args.length - 1];
			}

			if (command.equals("start")) {
				bootstrap.startServer();
				bootstrap.await();
				bootstrap.stopServer();
			} else if (command.equals("stop")) {
				bootstrap.stop();
			} else if (command.equals("restart")) {
				bootstrap.stop();
				// give me 2 seconds to shutdown the server
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {}
				bootstrap.startServer();
				bootstrap.await();
				bootstrap.stopServer();
			} else if (command.equals("reload")) {
				bootstrap.reload();
			}
			
			System.exit(0);
		} catch (Throwable t) {
			t.printStackTrace();
		}
	}
	
	public void stop() {
		sendCommand(SHUTDOWN);
	}

	public void reload() {
		sendCommand(RELOAD);
	}
	
	private void sendCommand(String command) {
		try {
            Socket socket = new Socket("127.0.0.1", port);
            OutputStream stream = socket.getOutputStream();
            for (int i = 0; i < command.length(); i++) {
                stream.write(command.charAt(i));
            }
            stream.flush();
            stream.close();
            socket.close();
        } catch (IOException e) {
            getLogger().error("IOException occurred: ", e);
        }
	}
	
	public void await() {
		// Set up a server socket to wait on
        ServerSocket serverSocket = null;
        try {
            serverSocket =
                new ServerSocket(port, 1,
                                 InetAddress.getByName("127.0.0.1"));
        } catch (IOException e) {
            getLogger().error("Bootstrap.await: create[" + port + "]: ", e);
            System.exit(1);
        }

        // Loop waiting for a connection and a valid command
        while (true) {

            // Wait for the next connection
            Socket socket = null;
            InputStream stream = null;
            try {
                socket = serverSocket.accept();
                socket.setSoTimeout(10 * 1000);  // Ten seconds
                stream = socket.getInputStream();
            } catch (AccessControlException ace) {
                getLogger().warn("StandardServer.accept security exception: " + ace.getMessage(), ace);
                continue;
            } catch (IOException e) {
                getLogger().error("StandardServer.await: accept: ", e);
                System.exit(1);
            }

            // Read a set of characters from the socket
            StringBuffer command = new StringBuffer();
            int expected = 1024; // Cut off to avoid DoS attack
            while (expected < SHUTDOWN.length()) {
                if (random == null)
                    random = new Random(System.currentTimeMillis());
                expected += (random.nextInt() % 1024);
            }
            while (expected > 0) {
                int ch = -1;
                try {
                    ch = stream.read();
                } catch (IOException e) {
                    getLogger().warn("Bootstrap.await: read: ", e);
                    ch = -1;
                }
                if (ch < 32)  // Control character or EOF terminates loop
                    break;
                command.append((char) ch);
                expected--;
            }

            // Close the socket now that we are done with it
            try {
                socket.close();
            } catch (IOException e) {
            }

            // Match against our command string
            if (command.toString().equals(SHUTDOWN)) {
                break;
            } else if (command.toString().equals(RELOAD)) {
            	try {
					server.reload();
				} catch (Exception e) {
					getLogger().error("Bootstrap.reloading failed", e);
				}
            } else {
                getLogger().warn("Bootstrap.await: Invalid command '" +
                                   command.toString() + "' received");
            }
        }

        // Close the server socket and return
        try {
            serverSocket.close();
        } catch (IOException e) {
        }

	}

}


2.server class 如下:

public class Server extends org.mortbay.jetty.Server {
	//~ Static fields/initializers =============================================

	private static final Logger logger = LoggerFactory.getLogger(Server.class);
	
	//~ Instance fields ========================================================
	
	private ClassPathXmlApplicationContext applicationContext;
	private Handler webapp;
	private RemotingServer remotingServer;
	
	
	//~ Constructors ===========================================================

	public Server() {
	}
	
	//~ Methods ================================================================
	
	private void initApplicationContext() {
		String configLocation = Configuration.get("spring.config.location", "applicationContext*.xml");
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
		context.setConfigLocation(context.CLASSPATH_ALL_URL_PREFIX + configLocation);
		context.refresh();
		applicationContext = context;
	}
	
	//private void initYPFS() {
	//	YPFS.initialize(null);
	//}
	
	private SecurityHandler createSecurityHandler() {
		return new SecurityHandler();
	}

	private SessionHandler createSessionHandler() {
		//SessionManager sessionManager = (SessionManager) applicationContext.getBean("jettySessionManager");
		//if (sessionManager == null) {
		//	logger.error("SessionManager not configured! use default: HashSessionManager");
		SessionManager sessionManager = new HashSessionManager();
		//}
		sessionManager.setSessionDomain("." + Configuration.get("webapp.domain"));
		return new SessionHandler(sessionManager);
	}
	
	private ErrorHandler createErrorHandler() {
		ErrorHandler handler = new ErrorHandler();
		handler.setShowStacks(Configuration.getBoolean("devmode", false));
		return handler;
	}
	
	public void reload() throws Exception {
		applicationContext.refresh();
		webapp.stop();
		webapp.start();
	}
	
	public void initialize() throws Exception {
		initApplicationContext();
		//initYPFS();
		
		Connector connector = new SelectChannelConnector();
		connector.setPort(Configuration.getInteger("server.port", 8080));
		setConnectors(new Connector[] { connector });
		
		webapp = initWebAppHandler();
		
		if (Configuration.getBoolean("devmode", false)) {
			// setup static context for development
			List handlers = new ArrayList(3);
			handlers.add(webapp);
			if (Configuration.get("server.media.vhosts") != null) {
				handlers.add(initStaticContext());
			}
			
			ContextHandlerCollection contexts = new ContextHandlerCollection();
			contexts.setHandlers(handlers.toArray(new Handler[handlers.size()]));
			setHandler(contexts);
		} else {
			setHandler(webapp);
		}
	}
	
	private Handler initStaticContext() {
		ResourceHandler staticHandler = new ResourceHandler();
		ContextHandler staticContext = new ContextHandler();
		staticContext.setContextPath("/");
		staticContext.setResourceBase(Configuration.get("server.media.war"));
		staticContext.setHandler(staticHandler);
		
		String vhosts = Configuration.get("server.media.vhosts", "");
		logger.info("Starting media server, vhosts: {}", vhosts);
		staticContext.setVirtualHosts(StringUtils.split(vhosts));

		return staticContext;
	}
	
	/* (non-Javadoc)
	 * @see org.mortbay.jetty.Server#doStop()
	 */
	@Override
	protected void doStop() throws Exception {
		logger.info("Shutting down...");
		super.doStop();
		
		if (remotingServer != null) {
			logger.info("Stopping remoting server...");
			remotingServer.stop();
		}
		
		applicationContext.destroy();
	}

	
	private Handler initWebAppHandler() throws IOException {
		WebAppContext context = new WebAppContext(createSecurityHandler(), createSessionHandler(), null, createErrorHandler());
		context.setDefaultsDescriptor("com/net365/server/jetty/webdefault.xml");
		context.setContextPath(Configuration.get("webapp.contextPath", "/"));
		context.setWar(Configuration.get("server.war"));
		context.setExtractWAR(false);
		context.setParentLoaderPriority(true);
		context.setTempDirectory(new File(Configuration.get("server.tmpDir")));
		context.setAttribute(B2CEshop.APPLICATION_CONTEXT_KEY, applicationContext);

		if (Configuration.getBoolean("devmode", false)) {
			String vhosts = Configuration.get("server.vhosts", "");
			logger.info("Starting server in DevMode, vhosts: {}", vhosts);
			context.setVirtualHosts(StringUtils.split(vhosts));
		}
		
		InputStream in = null;
		
		try {
			Resource resource = context.getWebInf().addPath("urlrewrite.xml");
			if (resource == null || !resource.exists()) {
				logger.error("Url rewrite rules not found, url rewrite will not be supported");
				return context;
			}
			in = resource.getInputStream();
			
			RewriteHandler handler = new RewriteHandler();
			handler.setHandler(context);
			handler.setRules(loadRewriteRules(in));
			handler.setActionExtension(Configuration.get("webapp.action.extension"));
			
			return handler;
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					logger.error("Error closing urlrewrite configuration file", e);
				}
			}
		}
	}
	
	private static Rule[] loadRewriteRules(InputStream in) {		
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(true);
        factory.setNamespaceAware(true);
        factory.setIgnoringComments(true);
        factory.setIgnoringElementContentWhitespace(true);
        
        DocumentBuilder parser;
        try {
            parser = factory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            logger.error("Unable to setup XML parser for reading conf", e);
            return null;
        }
        
        DefaultHandler handler = new DefaultHandler();
        parser.setErrorHandler(handler);
        parser.setEntityResolver(handler);

        List rules = new ArrayList();
        
        try {
            Document doc = parser.parse(in);
            
            Element rootElement = doc.getDocumentElement();
            NodeList categoryList = rootElement.getChildNodes();
            for (int i = 0; i < categoryList.getLength(); i++) {
                Node node = categoryList.item(i);

                if (node.getNodeType() == Node.ELEMENT_NODE &&
                        ((Element) node).getTagName().equals("category")) {
                	String categoryName = getAttrValue(node, "name");
                	
                	NodeList ruleList = node.getChildNodes();
                	
                	for (int j = 0; j < ruleList.getLength(); j++) {
                		Node subNode = ruleList.item(j);
                		
                		if (subNode.getNodeType() == Node.ELEMENT_NODE &&
                				((Element) subNode).getTagName().equals("rule")) {
                			Element ruleElement = (Element) subNode;
                			
                			RewriteRegexRule rule = new RewriteRegexRule();
                			rule.setCategory(categoryName);
                			rule.setRegex(getNodeValue(ruleElement.getElementsByTagName("from").item(0)));
                			rule.setReplacement(getNodeValue(ruleElement.getElementsByTagName("to").item(0)));

                			rules.add(rule);
                		}
                	}
                }
            }
        } catch (SAXParseException e) {
            logger.error("Parse error on line " + e.getLineNumber() + " " + e.getMessage(), e);
        } catch (Exception e) {
            logger.error("Exception loading conf " + e.getMessage(), e);
        }
        
        return rules.toArray(new Rule[rules.size()]);
	}
	
	private static String getNodeValue(Node node) {
        if (node == null) return null;
        NodeList nodeList = node.getChildNodes();
        if (nodeList == null) return null;
        Node child = nodeList.item(0);
        if (child == null) return null;
        if ((child.getNodeType() == Node.TEXT_NODE)) {
            String value = ((Text) child).getData();
            return value.trim();
        }
        return null;
    }
	
    private static String getAttrValue(Node n, String attrName) {
        if (n == null) return null;
        NamedNodeMap attrs = n.getAttributes();
        if (attrs == null) return null;
        Node attr = attrs.getNamedItem(attrName);
        if (attr == null) return null;
        String val = attr.getNodeValue();
        if (val == null) return null;
        return val.trim();
    }
}

这个其中一个小段,还有一些我的应用中加入的。哈哈。。

张宋付
粉丝 28
博文 15
码字总数 11591
作品 0
杭州
程序员
私信 提问
加载中
此博客有 3 条评论,请先登录后再查看。
spring内嵌jetty容器,实现main方法启动web项目

Jetty 是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对...

osc_2oi3ausc
2018/06/05
5
0
jetty 介绍以及小例子

Jetty 是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对...

osc_k6z4gwqi
2018/08/08
3
0
jetty服务器原理与maven集成

jetty服务器原理+MyEclipse下与Maven集成 Jetty 是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布...

|瑾诺学长|
2018/08/21
0
0
支持JSP和Servlet的Web服务器

支持JSP和Servlet的Web服务器 1、Tomcat 服务器 目前非常流行的Tomcat服务器是Apache-Jarkarta开源项目中的一个子项目,是一个小型、轻量级的支持JSP和Servlet 技术的Web服务器,也是初学者学...

osc_bskh1wlw
2019/03/08
3
0
Jetty介绍以及配置

转载:http://blog.csdn.net/xinxin19881112/article/details/5870677 Jetty是什么 Jetty项目简介 Jetty是一个开源、基于标准、全功能实现的JAVA服务器。它在Apache2.0协议下发布,因此可以自...

hawapple
2018/07/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

使用getApplication()作为上下文的对话框抛出“无法添加窗口-令牌null不适用于应用程序”

问题: My Activity is trying to create an AlertDialog which requires a Context as a parameter. 我的活动试图创建一个AlertContext,它需要一个Context作为参数。 This works as expect......

法国红酒甜
29分钟前
0
0
java常用开发支持类库

UUID类 UUID是一个生成无重复字符串的程序类(JDK1.5之后出现),这个程序类的主要功能是根据时间戳实现一个自动的无重复的字符串定义(无重复指的是出现重复的概率极低)。 一般在获取UUID时...

哼着我的小调调
39分钟前
15
0
亚马逊测评买家号多开_可以解决这个问题嘛?_微信公众号: VMlogin中文版

对于很多亚马逊卖家来说,做亚马逊测评是并不可少的,都在为了自己的店铺能够获得更多的销售,着重培养自己产品的各项属性,以求获得一个更好的权重排名从而获得更多的曝光,但是在旺季期间亚...

竹节猫-ASOer
45分钟前
10
0
Java基础系列——数组之java.util.Arrays使用以及可能出现的异常(12)

java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比 如排序和搜索)的各种方法。常用方法如下所示: boolean equals(int[] a,int[] b) 判断两个数组是否相等。 String toStrin...

卢佳鹏
今天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部