zoukankan      html  css  js  c++  java
  • Jetty

      Jetty作为Servlet服务器,和Tomcat一样也是成名已久,但是和tomcat不同的是它的体量较小,作为大型企业的服务器资格不足,但是作为分布式服务器和小型企业服务器还是很不错的选择,与作为补丁服务器的tomcat自然有些差距,介绍下jetty。

    这里是Jetty和Tomcat的比较:https://blog.51cto.com/825272560/2058729

    Jetty的架构:

      Jetty和Tomcat都采用了观察者模式,定义的接口都是LifeCycle,但是Jetty的较简单,注意Jetty中所有的组件都是有生命周期的,包括Server,也就是说Jetty的起点是LifeCycle接口,所以下面就不再提这个接口了。

      Jetty定义了两个接口,分别是Handler,HandlerContainer;这两个接口代表了Jetty的两个重要的功能,同时Jetty提供了抽象实现类AbstractHandler和AbstractHandlerContainer,注意AbstractHandlerContainer继承了AbstractHandler,他们是Jetty的默认实现。还有AbstractHandlerContainer抽象类,这个抽象类又继承了AbstractHandlerContainer,至此,Jetty的功能抽象类都已经完成。

     HandlerWrapper

      这是个包装类,人如其名,看下它的结构和属性:

      HandlerWrapper包装了一个Handler,这个Handler需要你自己决定你需要什么样的handler,这个Handler与后面讲的Jetty的两种实现方式有关。同时Server也继承了HandlerWrapepr,Server继承它的原因是因为Server是Jetty的启动类,所以这个Handler需要被Sever引用,并通过生命周期管理这个handler,仅此而已。

    下面是Jetty的Handler的两种实现方式

    1. ScopedHandler

      这个Handler继承自HandlerWrapper,这是个抽象类无关紧要,但是jetty为我们提供了这个抽象类的实现子类,这些是我们需要考虑的选择。

    如ServletHandler:

     1 public class ServletHandler extends ScopedHandler {
     2     private static final Logger LOG = Log.getLogger(ServletHandler.class);
     3     public static final String __DEFAULT_SERVLET = "default";
     4     private ServletContextHandler _contextHandler;
     5     private ServletContext _servletContext;
     6     private FilterHolder[] _filters = new FilterHolder[0];
     7     private FilterMapping[] _filterMappings;
     8     private int _matchBeforeIndex = -1;
     9     private int _matchAfterIndex = -1;
    10     private boolean _filterChainsCached = true;
    11     private int _maxFilterChainsCacheSize = 512;
    12     private boolean _startWithUnavailable = false;
    13     private boolean _ensureDefaultServlet = true;
    14     private IdentityService _identityService;
    15     private boolean _allowDuplicateMappings = false;
    16     private ServletHolder[] _servlets = new ServletHolder[0];
    17     private ServletMapping[] _servletMappings;
    18     private final Map<String, FilterHolder> _filterNameMap = new HashMap();
    19     private List<FilterMapping> _filterPathMappings;
    20     private MultiMap<FilterMapping> _filterNameMappings;
    21     private final Map<String, ServletHolder> _servletNameMap = new HashMap();
    22     private PathMappings<ServletHolder> _servletPathMap;
    23     private ListenerHolder[] _listeners = new ListenerHolder[0];
    24     private boolean _initialized = false;
    25     protected final ConcurrentMap<String, FilterChain>[] _chainCache = new ConcurrentMap[31];
    26     protected final Queue<String>[] _chainLRU = new Queue[31];

    这个类允许你实现自己的filter,它会在调用Servlet之前执行这些filter。

    如ContextHandler:

     1 public class ContextHandler extends ScopedHandler implements Attributes, Graceful {
     2     public static final int SERVLET_MAJOR_VERSION = 3;
     3     public static final int SERVLET_MINOR_VERSION = 1;
     4     public static final Class<?>[] SERVLET_LISTENER_TYPES = new Class[]{ServletContextListener.class, ServletContextAttributeListener.class, ServletRequestListener.class, ServletRequestAttributeListener.class, HttpSessionIdListener.class, HttpSessionListener.class, HttpSessionAttributeListener.class};
     5     public static final int DEFAULT_LISTENER_TYPE_INDEX = 1;
     6     public static final int EXTENDED_LISTENER_TYPE_INDEX = 0;
     7     private static final String UNIMPLEMENTED_USE_SERVLET_CONTEXT_HANDLER = "Unimplemented {} - use org.eclipse.jetty.servlet.ServletContextHandler";
     8     private static final Logger LOG = Log.getLogger(ContextHandler.class);
     9     private static final ThreadLocal<ContextHandler.Context> __context = new ThreadLocal();
    10     private static String __serverInfo = "jetty/" + Server.getVersion();
    11     public static final String MANAGED_ATTRIBUTES = "org.eclipse.jetty.server.context.ManagedAttributes";
    12     public static final String MAX_FORM_KEYS_KEY = "org.eclipse.jetty.server.Request.maxFormKeys";
    13     public static final String MAX_FORM_CONTENT_SIZE_KEY = "org.eclipse.jetty.server.Request.maxFormContentSize";
    14     public static final int DEFAULT_MAX_FORM_KEYS = 1000;
    15     public static final int DEFAULT_MAX_FORM_CONTENT_SIZE = 200000;
    16     protected ContextHandler.Context _scontext;
    17     private final AttributesMap _attributes;
    18     private final Map<String, String> _initParams;
    19     private ClassLoader _classLoader;
    20     private String _contextPath;
    21     private String _contextPathEncoded;
    22     private String _displayName;
    23     private Resource _baseResource;
    24     private MimeTypes _mimeTypes;
    25     private Map<String, String> _localeEncodingMap;
    26     private String[] _welcomeFiles;
    27     private ErrorHandler _errorHandler;
    28     private String[] _vhosts;
    29     private boolean[] _vhostswildcard;
    30     private String[] _vconnectors;
    31     private Logger _logger;
    32     private boolean _allowNullPathInfo;
    33     private int _maxFormKeys;
    34     private int _maxFormContentSize;
    35     private boolean _compactPath;
    36     private boolean _usingSecurityManager;
    37     private final List<EventListener> _eventListeners;
    38     private final List<EventListener> _programmaticListeners;
    39     private final List<ServletContextListener> _servletContextListeners;
    40     private final List<ServletContextListener> _destroySerletContextListeners;
    41     private final List<ServletContextAttributeListener> _servletContextAttributeListeners;
    42     private final List<ServletRequestListener> _servletRequestListeners;
    43     private final List<ServletRequestAttributeListener> _servletRequestAttributeListeners;
    44     private final List<ContextHandler.ContextScopeListener> _contextListeners;
    45     private final List<EventListener> _durableListeners;
    46     private String[] _protectedTargets;
    47     private final CopyOnWriteArrayList<ContextHandler.AliasCheck> _aliasChecks;
    48     private volatile ContextHandler.Availability _availability;

    这个类看起来才像正儿八经的容器类,它允许你接触到容器上下文,web容器的handler一般都会继承自这个类。

    还有ServletContextHandler:

     1 public class ServletContextHandler extends ContextHandler {
     2     private static final Logger LOG = Log.getLogger(ServletContextHandler.class);
     3     public static final int SESSIONS = 1;
     4     public static final int SECURITY = 2;
     5     public static final int GZIP = 4;
     6     public static final int NO_SESSIONS = 0;
     7     public static final int NO_SECURITY = 0;
     8     protected final DecoratedObjectFactory _objFactory;
     9     protected Class<? extends SecurityHandler> _defaultSecurityHandlerClass;
    10     protected SessionHandler _sessionHandler;
    11     protected SecurityHandler _securityHandler;
    12     protected ServletHandler _servletHandler;
    13     protected GzipHandler _gzipHandler;
    14     protected int _options;
    15     protected JspConfigDescriptor _jspConfig;
    16     private boolean _startListeners;

    这个类继承自ContextHandler,同时它又允许你加入Jetty实现的一些特定Handler,如SessionHandler等。

    后面还有一些其他的继承自ScopedHandler的Handler,原理是一样的,这些Handler最后都会执行Servlet的Service方法。

    2. HandlerCollection

      这个类继承自AbstractHandlerContainer,这个类属于暴力类,举个例子:

     1 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
     2         if (this.isStarted()) {
     3             HandlerCollection.Handlers handlers = (HandlerCollection.Handlers)this._handlers.get();
     4             if (handlers == null) {
     5                 return;
     6             }
     7 
     8             MultiException mex = null;
     9             Handler[] var7 = handlers._handlers;
    10             int var8 = var7.length;
    11 
    12             for(int var9 = 0; var9 < var8; ++var9) {
    13                 Handler handler = var7[var9];
    14 
    15                 try {
    16                     handler.handle(target, baseRequest, request, response);
    17                 } catch (RuntimeException | IOException var12) {
    18                     throw var12;
    19                 } catch (Exception var13) {
    20                     if (mex == null) {
    21                         mex = new MultiException();
    22                     }
    23 
    24                     mex.add(var13);
    25                 }
    26             }
    27 
    28             if (mex != null) {
    29                 if (mex.size() == 1) {
    30                     throw new ServletException(mex.getThrowable(0));
    31                 }
    32 
    33                 throw new ServletException(mex);
    34             }
    35         }
    36 
    37     }

      这个类的作用很简单,将需要处理的handler加到这个集合类中,并把这个集合类注入到Server中的Handler中,这个类就会循环处理其中的Handler。

    Connector和Tomcat中的Connector一样,负责接受请求,将请求交给Server,由Server交给Handler.hande处理:

     1 public void handle(HttpChannel channel) throws IOException, ServletException {
     2         String target = channel.getRequest().getPathInfo();
     3         Request request = channel.getRequest();
     4         Response response = channel.getResponse();
     5         if (LOG.isDebugEnabled()) {
     6             LOG.debug("{} {} {} on {}", new Object[]{request.getDispatcherType(), request.getMethod(), target, channel});
     7         }
     8 
     9         if (!HttpMethod.OPTIONS.is(request.getMethod()) && !"*".equals(target)) {
    10             this.handle(target, request, request, response);
    11         } else if (!HttpMethod.OPTIONS.is(request.getMethod())) {
    12             request.setHandled(true);
    13             response.sendError(400);
    14         } else {
    15             this.handleOptions(request, response);
    16             if (!request.isHandled()) {
    17                 this.handle(target, request, request, response);
    18             }
    19         }
    20 
    21         if (LOG.isDebugEnabled()) {
    22             LOG.debug("handled={} async={} committed={} on {}", new Object[]{request.isHandled(), request.isAsyncStarted(), response.isCommitted(), channel});
    23         }
    24 
    25     }

      这个Connector实现了LifeCycle和Container以及Graceful接口,LifeCycle和Container接口方便设置一些属性和将自己注册到Server上等功能。

    至此Jetty的大体流程搞清楚了,自己的学习,可能有错误,后续持续修正。

  • 相关阅读:
    Nginx进程信号管理
    Nginx配置缓存服务器
    访问Nginx显示目录
    kubeadm快速安装k8s
    《构建之法》读书笔记(一)
    Android Studio连接SQLite数据库与SQLite Studio实时同步的实现
    关于sqlite数据库与sqlite studio
    AS之去掉顶部标题栏
    今日学习
    AS之AlertDialog使用
  • 原文地址:https://www.cnblogs.com/YsirSun/p/12591158.html
Copyright © 2011-2022 走看看