65.9K
CodeProject 正在变化。 阅读更多。
Home

在应用程序中运行 Jetty Web 服务器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (16投票s)

2010年11月16日

CPOL

5分钟阅读

viewsIcon

186714

downloadIcon

2149

不要将您的应用程序部署到Jetty中,而是将Jetty部署到您的应用程序中

目录

引言

本文的目的是让您快速了解如何在不真正运行应用程序外部的Web服务器并且不创建WAR文件进行部署的情况下,构建和部署您的Web应用程序。目前,我正在开发一个项目,它是一个后台计算引擎,并提供一个简单的Web界面供支持和业务用户监控正在进行的活动。在部署我们的应用程序时,我们只需在应用程序内部启动Jetty Web服务器,就可以轻松访问Web应用程序。

如果您访问Jetty wiki,会提到Jetty的口号是“不要将您的应用程序部署到Jetty中,而是将Jetty部署到您的应用程序中。” 在本文中,我们将通过一个 nice and simple 的应用程序来阐述这个口号。

下载Jetty

在开始创建项目之前,我们需要从Jetty@eclipse downloads网站下载任何稳定版本的Jetty JAR文件。在本文中,我使用了Jetty 7。每个Jetty网站都附带以下捆绑包。

  • 核心Jetty Web服务器 (HTTP & Websocket)
  • 核心Jetty Servlet容器
  • JNDI、JMX、OSGi、JASPI模块
  • HTTP客户端

除了Jetty JAR之外,我们还需要在系统上安装JSK 1.6和Eclipse 3.5。一旦这三样东西准备就绪,我们就可以创建我们的应用程序了。

创建一个Eclipse项目

您只需要按照下面提到的步骤在Eclipse中创建一个Java项目。

  • 转到Eclipse的“文件”菜单并创建一个Java项目。
  • 如果默认的JRE选项设置为JavaSE-1.6,则保留该选项。
  • 点击“库”选项卡并选择Jetty JAR文件。
  • 项目创建完成后,在项目中再添加两个文件夹:“page”和“WEB-INF”。

项目创建完成后,项目结构应如下所示:

initial_project_structure.png

由于项目已设置完毕,我们就可以创建将在应用程序内部启动的Web应用程序了。

创建一个Web应用程序

  1. WEB-INF文件夹中创建一个部署描述符(即web.xml)。这是一个非常基本的描述符,其中只包含欢迎页面的文件名。
     <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    	<welcome-file-list>
    		<welcome-file>page/index.jsp</welcome-file> 
    	</welcome-file-list>
    </web-app> 
  2. 接下来,我们需要在page文件夹中创建一个index.jsp文件,当我们在Web浏览器中访问URL时,将显示该文件。
    <%@ page language="java" contentType="text/html; 
    charset=ISO-8859-1 pageEncoding="ISO-8859-1"%> 
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    	"http://www.w3.org/TR/html4/loose.dtd">
    <html> 
    	<head> 
    		<meta http-equiv="Content-Type" 
    			content="text/html; charset=ISO-8859-1">
    		<title>Embedding Jettye</title>
    	</head>
    	<body>
    		<h2>Running Jetty web server from our application!!</h2>
    	</body>
    </html>  

创建一个Jetty服务器实例

  1. 首先,我们构建一个WebAppContext,其中可以定义部署描述符的位置并设置应用程序的上下文路径。这个WebAppContext需要设置Jetty服务器的头部,这将在本节的后面部分进行说明。以下代码描述了如何构建WebAppContext
    package blog.runjetty.context;
    
    import org.eclipse.jetty.webapp.WebAppContext;
    
    public class AppContextBuilder {
    	
    	private WebAppContext webAppContext;
    	
    	public WebAppContext buildWebAppContext(){
    		webAppContext = new WebAppContext();
    		webAppContext.setDescriptor(webAppContext + "/WEB-INF/web.xml");
    		webAppContext.setResourceBase(".");
    		webAppContext.setContextPath("/runJetty");
    		return webAppContext;
    	}
    }  
  2. 创建WebAppContext后;我们创建一个负责操作org.eclipse.jetty.server.Server类实例的类。为此,我构建了一个包装器JettyServer。它定义了运行端口(默认为8585),设置上下文头部(即设置WebAppContext),启动/停止服务器,并检查服务器是否正在运行。
    package blog.runjetty.server;
    
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.server.handler.ContextHandlerCollection;
    
    public class JettyServer {
    
    	private Server server;
    	
    	public JettyServer() {
    		this(8585);
    	}
    	public JettyServer(Integer runningPort) {
    		server = new Server(runningPort);
    	}
    	
    	public void setHandler(ContextHandlerCollection contexts) {
    		server.setHandler(contexts);
    	}
    	
    	public void start() throws Exception {
    		server.start();
    	}
    	
    	public void stop() throws Exception {
    		server.stop();
    		server.join();
    	}
    	
    	public boolean isStarted() {
    		return server.isStarted();
    	}
    	
    	public boolean isStopped() {
    		return server.isStopped();
    	}
    }

创建一个用户界面来启动和停止服务器

现在我们将构建一个简单的基于Swing的用户界面,其中包含一个启动/停止按钮。根据服务器的状态,它会启动服务器或关闭服务器。
  1. 创建一个ActionListener,它实际上会检查服务器的当前状态,并在执行任何操作时切换其状态。在我们的应用程序中,我们创建了ServerStartStopActionListner,它实现了ActionListener接口覆盖了actionPerformed方法。
    package blog.runjetty.ui.listener;
    
    import java.awt.Cursor;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    
    import blog.runjetty.server.JettyServer;
    
    public class ServerStartStopActionListner implements ActionListener {
    
    	private final JettyServer jettyServer;
    
    	public ServerStartStopActionListner(JettyServer jettyServer) {
    		this.jettyServer = jettyServer;
    	}
    
    	@Override
    	public void actionPerformed(ActionEvent actionEvent) {
    		 JButton btnStartStop =  (JButton) actionEvent.getSource();
    		 if(jettyServer.isStarted()){
    			 btnStartStop.setText("Stopping...");
    			 btnStartStop.setCursor(new Cursor(Cursor.WAIT_CURSOR));
    			 try {
    				jettyServer.stop();
    			} catch (Exception exception) {
    				exception.printStackTrace();
    			}
    			 btnStartStop.setText("Start");
    			 btnStartStop.setCursor
    				(new Cursor(Cursor.DEFAULT_CURSOR));
    		 }
    		 else if(jettyServer.isStopped()){
    			 btnStartStop.setText("Starting...");
    			 btnStartStop.setCursor(new Cursor(Cursor.WAIT_CURSOR));
    			 try {
    				jettyServer.start();
    			} catch (Exception exception) {
    				exception.printStackTrace();
    			}
    			 btnStartStop.setText("Stop");
    			 btnStartStop.setCursor
    				(new Cursor(Cursor.DEFAULT_CURSOR));
    		 }
    	}
    }
  2. 创建ActionListener后,我们需要创建一个JFrame。我们的ServerRunner继承了JFrame。它有一个JButton,该按钮已注册到ServerStartStopActionListner,以便在单击时执行启动或停止操作。
    package blog.runjetty.ui;
    import java.awt.BorderLayout;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    
    import blog.runjetty.server.JettyServer;
    import blog.runjetty.ui.listener.ServerStartStopActionListner;
    
    public class ServerRunner extends JFrame{
    	private static final long serialVersionUID = 8261022096695034L;
    	
    	private JButton btnStartStop;
    
    	public ServerRunner(final JettyServer jettyServer) {
    		super("Start/Stop Server");
    		setDefaultCloseOperation(EXIT_ON_CLOSE);
    		btnStartStop = new JButton("Start");
    		btnStartStop.addActionListener
    			(new ServerStartStopActionListner(jettyServer));
    		add(btnStartStop,BorderLayout.CENTER);
    		setSize(300,300);
    		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    			@Override
    			public void run() {
    				if(jettyServer.isStarted()) {
    					try {
    						jettyServer.stop();
    					} catch (Exception exception) {
    						exception.printStackTrace();
    					}
    				}
    			}
    		},"Stop Jetty Hook")); 
    		setVisible(true);
    	}
    } 
  3. ServerRunner中,我添加了一个ShutdownHook。因此,每当用户单击窗口右上角的关闭按钮时,它将首先检查服务器是否正在运行。如果正在运行,它将在退出之前停止服务器。

创建一个main方法

现在一切就绪,我们可以创建一个main方法来触发用户界面。以下代码展示了如何启动界面。
package blog.runjetty.main;

import java.awt.EventQueue;

import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;

import blog.runjetty.context.AppContextBuilder;
import blog.runjetty.server.JettyServer;
import blog.runjetty.ui.ServerRunner;

public class JettyFromMain {

	public static void main(String[] args) {
		ContextHandlerCollection contexts = new ContextHandlerCollection();
		
		contexts.setHandlers(new Handler[] 
			{ new AppContextBuilder().buildWebAppContext()});
		
		final JettyServer jettyServer = new JettyServer();
		jettyServer.setHandler(contexts);
		Runnable runner = new Runnable() {
			@Override
			public void run() {
				new ServerRunner(jettyServer);
			}
		};
		EventQueue.invokeLater(runner);
	}
}

在这里,您可以发现我首先创建了一个ContextHandlerCollection并将我们的WebAppContext添加进去,然后再将处理器设置到我们的服务器中。在run()方法中,我创建了一个ServerRunner的实例。在实现以下代码之后,我们的项目结构应该如下所示:

final_project_structure.png

运行应用程序

现在是时候测试我们的应用程序了。按照步骤执行以下操作来运行应用程序,并亲自了解它是如何工作的。

  1. 从Eclipse运行应用程序。
  2. 您应该会看到以下窗口

    start_jetty_window.png

  3. 单击“开始”按钮。等待按钮文本更改为“停止”,如下图所示

    stop_jetty_window.png

  4. 打开Web浏览器并访问URL https://:8585/runJetty/
    您的Web应用程序应该已启动并运行,如下图所示

    web_application_running.png

  5. 现在,单击“停止”按钮或直接关闭窗口。
  6. 如果单击“停止”按钮,请等待出现“开始”文本。然后刷新您的浏览器窗口,以验证您的Web应用程序不再运行,如下图所示

    web_application_not_running.png - Click to enlarge image

结论

如您所见,在我们的应用程序中构建和部署Jetty服务器非常容易。现在您已经准备好自行探索,例如仅用几行代码创建SSL连接,使用Spring MVC或任何其他Java Web技术构建更复杂的Web应用程序。有关更多信息,请访问官方Jetty网站:http://www.eclipse.org/jetty/,或者随时在此处发表评论。欢迎任何建议或意见!

© . All rights reserved.