Jetty 是一个开源的servlet容器,它为基于Java的web容器,例如JSP和servlet提供运行环境。Jetty是使用Java语言编写的,它的API以一组JAR包的形式发布。开发人员可以将Jetty容器实例化成一个对象,可以迅速为一些独立运行(stand-alone)的Java应用提供网络和web连接。
由于目前流行的Web开发逐步开始去J2EE化,准确的说,是去掉一些不常用的标准,笔者所在的支付清算企业正在实施的新一代电子银行系统,就规划不再使用WAS,原因很简单,太重!计划使用Jetty作为前端与后台服务的网关来使用。所以使用Jetty的嵌入式属性非常适合。通过两周源代码的阅读,将最基本的结构和使用方法写出了,但愿有读者能够看到,少走些弯路。本文基于9.4版本。
一、Jetty使用入门例子
先上代码:
package org.eclipse.jetty.embedded;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
public class HelloWorld extends AbstractHandler
{
@Override
public void handle( String target,
Request baseRequest,
HttpServletRequest request,
HttpServletResponse response ) throws IOException,
ServletException
{
// Declare response encoding and types
response.setContentType("text/html; charset=utf-8");
// Declare response status code
response.setStatus(HttpServletResponse.SC_OK);
// Write back response
response.getWriter().println("<h1>Hello World</h1>");
// Inform jetty that this request has now been handled
baseRequest.setHandled(true);
}
public static void main( String[] args ) throws Exception
{
Server server = new Server(8080);
server.setHandler(new HelloWorld());
server.start();
server.join();
}
}
此代码在源代码中的embedded目录下,通过它能够快速上手,先run起来。简单几行代码,即可实现基本的HTTP Server功能,后面就是写Handle处理了。
二、Jetty原理结构
Jetty设计非常优秀,学习起来也比较愉悦。通过执行server.dump()能够概览真个Server的内部架构:
org.eclipse.jetty.server.Server@69d0a921 - STARTED
+MANAGED qtp168423058{STARTED,10<=10<=200,i=5,q=0} - STARTED
| +- 14 qtp168423058-14 RUNNABLE @ sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
| +- 16 qtp168423058-16-lowPrioritySelector BLOCKED @ org.eclipse.jetty.io.ManagedSelector$SelectorProducer.produce(ManagedSelector.java:244) prio=1
| +- 18 qtp168423058-18-lowPrioritySelector BLOCKED @ org.eclipse.jetty.io.ManagedSelector$SelectorProducer.produce(ManagedSelector.java:244) prio=1
| +- 11 qtp168423058-11 TIMED_WAITING @ sun.misc.Unsafe.park(Native Method) IDLE
| +- 19 qtp168423058-19-acceptor-0@122bbfe5-ServerConnector@446cdf90{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} RUNNABLE @ sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) prio=3
| +- 17 qtp168423058-17 RUNNABLE @ sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
| +- 13 qtp168423058-13 TIMED_WAITING @ sun.misc.Unsafe.park(Native Method) IDLE
| +- 12 qtp168423058-12 TIMED_WAITING @ sun.misc.Unsafe.park(Native Method) IDLE
| +- 20 qtp168423058-20 TIMED_WAITING @ sun.misc.Unsafe.park(Native Method) IDLE
| +- 15 qtp168423058-15 TIMED_WAITING @ sun.misc.Unsafe.park(Native Method) IDLE
| +- jobs
+MANAGED ServerConnector@446cdf90{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} - STARTED
| +UNMANAGED org.eclipse.jetty.server.Server@69d0a921 - STARTED
| +UNMANAGED qtp168423058{STARTED,10<=10<=200,i=5,q=0} - STARTED
| +MANAGED org.eclipse.jetty.util.thread.ScheduledExecutorScheduler@27d6c5e0 - STARTED
| +POJO org.eclipse.jetty.io.ArrayByteBufferPool@799f7e29
| +MANAGED HttpConnectionFactory@5b480cf9[HTTP/1.1] - STARTED
| | +POJO HttpConfiguration@4b85612c{32768/8192,8192/8192,https://:0,[]}
| +MANAGED org.eclipse.jetty.server.ServerConnector$ServerConnectorManager@277050dc - STARTED
| | +MANAGED org.eclipse.jetty.io.ManagedSelector@ed17bee id=0 keys=0 selected=0 id=0
| | | +- sun.nio.ch.WindowsSelectorImpl@3c2c789a keys=0
| | +MANAGED org.eclipse.jetty.io.ManagedSelector@11028347 id=1 keys=0 selected=0 id=1
| | +- sun.nio.ch.WindowsSelectorImpl@3aeca036 keys=0
| +POJO sun.nio.ch.ServerSocketChannelImpl[/0:0:0:0:0:0:0:0:8080]
| +POJO qtp168423058-19-acceptor-0@122bbfe5-ServerConnector@446cdf90{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
+MANAGED org.eclipse.jetty.util.thread.ScheduledExecutorScheduler@238e0d81 - STARTED
+MANAGED org.eclipse.jetty.server.handler.HandlerCollection@5c29bfd[org.eclipse.jetty.server.handler.ContextHandlerCollection@7aec35a[],org.eclipse.jetty.server.handler.DefaultHandler@67424e82] - STARTED
| +MANAGED org.eclipse.jetty.server.handler.ContextHandlerCollection@7aec35a[] - STARTED
| +MANAGED org.eclipse.jetty.server.handler.DefaultHandler@67424e82 - STARTED
+MANAGED org.eclipse.jetty.server.handler.ErrorHandler@14899482 - STARTED
|
+> sun.misc.Launcher$AppClassLoader@73d16e93
+- file:/C:/Users/lenovo/workspace/webtest/bin/
+- file:/F:/jetty/lib/jetty-http-9.4.3.v20170317.jar
+- file:/F:/jetty/lib/jetty-server-9.4.3.v20170317.jar
+- file:/F:/jetty/lib/jetty-util-9.4.3.v20170317.jar
+- file:/F:/jetty/lib/servlet-api-3.1.jar
+- file:/F:/jetty/lib/jetty-io-9.4.3.v20170317.jar
+- file:/F:/jetty/lib/jetty-xml-9.4.3.v20170317.jar
+- sun.misc.Launcher$ExtClassLoader@7a81197d
可以看出,Server核心包括:ServerConnector,HandlerCollection,qtp三大部分,即连接、处理和线程池。上面加载的Jar包是服务器运行最小集了。
研究代码首先看懂util.component和thread部分,其中ContainerLifeCycle一定要看明白。你看了就知道上面这张图的意思啦。