zoukankan      html  css  js  c++  java
  • 《How Tomcat Works》读书笔记(三)--Connector(连接器)

    《How Tomcat Works》读书笔记(三)--Connector(连接器)

    这是《How Tomcat Works》第三四章的读书笔记。主要写了Tomcat4.0默认的连接器(Connector)的处理流程,后面Tomcat的连接器改为Coyote。

    1. 概述


    1.1 架构

    • HttpConector:监听Http请求、维护HttpProcessor对象池、处理Http请求(调用HttpProcessor对象进行处理)
    • HttpProcessor:解析请求(解析连接、解析请求行、解析请求头等等)、调用容器进行处理
    • Request:表示Http请求,实现了org.apache.catalina.Request接口。
    • Response:表示Http响应,实现了org.apache.catalina.Response接口。

    其中Request、Response就是代表Http请求、Http响应,实现了Servlet编程中HttpServletRequest、HttpServletResponse接口,这样符合Java EE编程标准。只是Tomcat在这里使用了许多的类、接口等等(如:RequestBase、HttpRequestImpl、RequestFacade),这样做就像Java Util包中哪些类库一样,反正看起来好复杂。

    1.2 HttpProcessor处理逻辑
    只是展示逻辑,省略一些具体的处理方式,省略了try-catch等等。

     1 /**
     2  * Process an incoming HTTP request on the Socket that has been assigned
     3  * to this Processor.  Any exceptions that occur during processing must be
     4  * swallowed and dealt with.
     5  *
     6  * @param socket The socket on which we are connected to the client
     7  */
     8 private void process(Socket socket) {
     9     boolean ok = true;
    10     boolean finishResponse = true;
    11     SocketInputStream input = null;
    12 
    13     // Construct and initialize the objects we will need
    14     // 构造对象,这里省略的许多的try-catch
    15     input = new SocketInputStream(socket.getInputStream(), connector.getBufferSize());
    16     // Http/1.1中新特性:长连接
    17     keepAlive = true;
    18     while (!stopped && ok && keepAlive) {
    19         finishResponse = true;
    20         request.setStream(input);
    21         request.setResponse(response);
    22         output = socket.getOutputStream();
    23         response.setStream(output);
    24         response.setRequest(request);
    25         ((HttpServletResponse) response.getResponse()).setHeader("Server", Constants.ServerInfo);
    26         
    27         // Parse the incoming request
    28         // 解析请求数据
    29         // 解析连接 
    30         parseConnection(socket);
    31         // 解析请求行
    32         parseRequest(input, output);
    33         if (!request.getRequest().getProtocol().startsWith("HTTP/0"))
    34             //解析请求头
    35             parseHeaders(input);
    36         if (http11) {
    37             // Sending a request acknowledge back to the client if
    38             // requested.
    39             ackRequest(output);
    40             // If the protocol is HTTP/1.1, chunking is allowed.
    41             if (connector.isChunkingAllowed())
    42                 response.setAllowChunking(true);
    43         }
    44         
    45         // Ask our Container to process this request
    46         // 调用Servlet容器处理请求
    47         ((HttpServletResponse) response).addDateHeader("Date", System.currentTimeMillis());
    48         connector.getContainer().invoke(request, response);
    49         
    50         // Finish up the handling of the request
    51         response.finishResponse();
    52         request.finishRequest();
    53         
    54         // Recycling the request and the response objects
    55         // 回收Request、Response对象:把该对象的状态复原使得下一次请求有自己独有的状态
    56         request.recycle();
    57         response.recycle();
    58     }       
    59 }

    2. 一些解释

    2.1 有状态的对象线程池
    有状态的对象线程池:池中每个对象有一个自己的线程,每个对象有自己的状态(域)。

    Connector(连接器)中HttpConnector接受请求,调用HttpProcessor对象处理请求。HttpConnector管理一系列的HttpProcessor对象,每个HttpProcessor对象有自己单独的后台线程,这样每次都使用一个线程处理请求。

    HttpConnector在最开始就启动池中所有的HttpProcessor对象,然后有请求来时从池中拿一个HttpProcessor对象进行处理。

     1 public void run() {
     2     // Loop until we receive a shutdown command
     3     while (!stopped) {
     4         // Accept the next incoming connection from the server socket
     5         Socket socket = null;
     6         // Hand this socket off to an appropriate processor
     7         // 从池中拿一个HttpProcessor
     8         HttpProcessor processor = createProcessor();
     9         // 调用HttpProcessor进行处理
    10         processor.assign(socket);
    11     }
    12 }

    HttpProcessor对象一开始就全部启动,等待HttpConnector分配socket进行处理。

     1 public void run() {
     2     // Process requests until we receive a shutdown signal
     3     while (!stopped) {
     4         // Wait for the next socket to be assigned
     5         // 在这里HttpProcessor对象会阻塞直到HttpConnector分配一个socket
     6         Socket socket = await();
     7         if (socket == null)
     8             continue;
     9         // Process the request from this socket
    10         // 进行处理
    11         process(socket);
    12         // Finish up this request
    13         // 处理完成,把该HttpProcessor放回HttpProcessor对象池中
    14         connector.recycle(this);
    15     }
    16 }

    HttpProcessor对象一开始就全部启动,然后会被阻塞(如上所示)直到HttpConnector分配socket。await()与assign(Socket socket)方法如下:

     1 /**
     2  * The socket we are currently processing a request for.  This object
     3  * is used for inter-thread communication only.
     4  */
     5 private Socket socket = null;
     6     
     7 /**
     8  * Is there a new socket available?
     9  */
    10 private boolean available = false;
    11 
    12 /**
    13  * Process an incoming TCP/IP connection on the specified socket.  Any
    14  * exception that occurs during processing must be logged and swallowed.
    15  * NOTE:  This method is called from our Connector's thread.  We
    16  * must assign it to our own thread so that multiple simultaneous
    17  * requests can be handled.
    18  *
    19  * @param socket TCP socket to process
    20  */
    21 synchronized void assign(Socket socket) {
    22     // Wait for the Processor to get the previous Socket
    23     // 如果已经分配,则等待
    24     while (available) {
    25         try {
    26             wait();
    27         } catch (InterruptedException e) {
    28         }
    29     }
    30     // Store the newly available Socket and notify our thread、
    31     // 分配socket
    32     this.socket = socket;
    33     available = true;
    34     notifyAll();
    35 }
    36 
    37 /**
    38  * Await a newly assigned Socket from our Connector, or null
    39  * if we are supposed to shut down.
    40  */
    41 private synchronized Socket await() {
    42     // Wait for the Connector to provide a new Socket
    43     // 如果没有分配,则等待
    44     while (!available) {
    45         try {
    46             wait();
    47         } catch (InterruptedException e) {
    48         }
    49     }
    50     // Notify the Connector that we have received this Socket
    51     // 把分配的socket返回
    52     Socket socket = this.socket;
    53     available = false;
    54     notifyAll();
    55     return socket;
    56 }

    最后每一次的Request、Response对象状态是不一样的,所以在处理完完成后,需要把Request、Response对象状态还原。

    1 // Recycling the request and the response objects
    2 request.recycle();
    3 response.recycle();

    2.2 解析处理
    HttpProcessor解析过程是一个耗时的过程,尤其是解析请求参数、Cookies时,所有Tomcat中设计为仅仅我们需要使用Parameter、Cookies时才解析。我们以Parameter为例:

    在需要使用Parameter方法时(如:getParameter()方法)时,就验证是否需要解析,如果没有解析就解析,否则直接使用。

     1 /**
     2  * The parsed parameters for this request.  This is populated only if
     3  * parameter information is requested via one of the
     4  * getParameter() family of method calls.  The key is the
     5  * parameter name, while the value is a String array of values for this
     6  * parameter.
     7  * 
     8  * IMPLEMENTATION NOTE - Once the parameters for a
     9  * particular request are parsed and stored here, they are not modified.
    10  * Therefore, application level access to the parameters need not be
    11  * synchronized.
    12  * 存放Parameter,继承HashMap,与HashMap基本无异
    13  */
    14 protected ParameterMap parameters = null;
    15 
    16 /**
    17  * Have the parameters for this request been parsed yet?
    18  * 是否已经解析
    19  */
    20 protected boolean parsed = false;
    21 
    22 /**
    23  * Parse the parameters of this request, if it has not already occurred.
    24  * If parameters are present in both the query string and the request
    25  * content, they are merged.
    26  */
    27 protected void parseParameters() {
    28     if (parsed)
    29         return;
    30     ParameterMap results = parameters;
    31     // 具体解析逻辑就不给出来了
    32     
    33     // Store the final results
    34     parsed = true;
    35     parameters = results;
    36 }
    37 
    38 public String getParameter(String name) {
    39     parseParameters();
    40     String values[] = (String[]) parameters.get(name);
    41     if (values != null)
    42         return (values[0]);
    43     else
    44         return (null);
    45 }

    3. 代码

    逻辑基本一致,但是自己省略了需要的具体逻辑,如仅仅解析了RequestURL等等。然后许多与Request的有关的类,我仅仅使用了HttpRequest全部代替了。

    Container、Connector接口:

     1 package note2;
     2 
     3 import javax.servlet.http.HttpServletRequest;
     4 import javax.servlet.http.HttpServletResponse;
     5 
     6 /**
     7  * Created by kanyuxia on 2017/4/27.
     8  * 模拟org.apache.catalina.Connector接口
     9  */
    10 public interface Connector {
    11     /**
    12      * Return the Container used for processing requests received by this
    13      * Connector.
    14      */
    15     Container getContainer();
    16 
    17     /**
    18      * Set the Container used for processing requests received by this
    19      * Connector.
    20      *
    21      * @param container The new Container to use
    22      */
    23     void setContainer(Container container);
    24 
    25     /**
    26      * Return the scheme that will be assigned to requests received
    27      * through this connector.  Default value is "http".
    28      */
    29     String getScheme();
    30 
    31     /**
    32      * Set the scheme that will be assigned to requests received through
    33      * this connector.
    34      *
    35      * @param scheme The new scheme
    36      */
    37     void setScheme(String scheme);
    38 
    39     /**
    40      * Create (or allocate) and return a Request object suitable for
    41      * specifying the contents of a Request to the responsible Container.
    42      */
    43     HttpServletRequest createRequest();
    44 
    45     /**
    46      * Create (or allocate) and return a Response object suitable for
    47      * receiving the contents of a Response from the responsible Container.
    48      */
    49     HttpServletResponse createResponse();
    50 
    51     /**
    52      * Invoke a pre-startup initialization. This is used to allow connectors
    53      * to bind to restricted ports under Unix operating environments.
    54      */
    55     void initialize();
    56 
    57 }
    58 
    59 package note2;
    60 
    61 import javax.servlet.ServletException;
    62 import java.io.IOException;
    63 
    64 /**
    65  * Created by kanyuxia on 2017/4/27.
    66  * 模拟org.apache.catalina.Container接口
    67  */
    68 public interface Container {
    69     /**
    70      * Process the specified Request, and generate the corresponding Response,
    71      * according to the design of this particular Container.
    72      *
    73      * @param request Request to be processed
    74      * @param response Response to be produced
    75      *
    76      * @exception IOException if an input/output error occurred while
    77      *  processing
    78      * @exception ServletException if a ServletException was thrown
    79      *  while processing this request
    80      */
    81     void invoke(HttpRequest request, HttpResponse response) throws IOException, ServletException;
    82 }
    View Code

    Request、Response相关类:

       1 package note2;
       2 
       3 import javax.servlet.*;
       4 import javax.servlet.http.*;
       5 import java.io.BufferedReader;
       6 import java.io.IOException;
       7 import java.io.InputStream;
       8 import java.io.UnsupportedEncodingException;
       9 import java.security.Principal;
      10 import java.util.*;
      11 
      12 /**
      13  * Created by kanyuxia on 2017/4/26.
      14  * Http请求对象
      15  */
      16 public class HttpRequest implements HttpServletRequest {
      17 
      18     // ---------------------------------Http Request Infomations
      19     /**
      20      * 存放Http request headers
      21      */
      22     private HashMap<String, ArrayList<String>> headers = new HashMap<>();
      23 
      24     /**
      25      * 存放Http request cookies
      26      */
      27     private ArrayList<Cookie> cookies = new ArrayList<>();
      28 
      29     /**
      30      * 存放Http请求参数:Query String or Form datas.
      31      * 只有当Servlet取参数时,才解析
      32      */
      33     private ParameterMap<String, String[]> parameterMap = null;
      34 
      35     /**
      36      * Have the parameters for this request been parsed yet?
      37      * 是否解析了Http Parameters
      38      */
      39     private boolean parameterPared = false;
      40 
      41     /**
      42      * The request URI associated with this request.
      43      * 请求URL地址
      44      */
      45     private String requestURI = null;
      46 
      47 
      48     /**
      49      * The input stream associated with this Request.
      50      */
      51     private InputStream input = null;
      52 
      53 
      54     // ---------------------------------------Servlet some infomations
      55 
      56     /**
      57      * The request attributes for this request.
      58      */
      59     private final HashMap<String, Object> attributes = new HashMap<>();
      60 
      61     /**
      62      * The Connector through which this Request was received.
      63      */
      64     private Connector connector = null;
      65 
      66 
      67     // --------------------------------------Some methods
      68     /**
      69      * 添加HTTP header
      70      * @param name header name
      71      * @param value header value
      72      */
      73     public void addHeader(String name, String value) {
      74         name = name.toLowerCase();
      75         ArrayList<String> values = headers.get(name);
      76         if (values != null) {
      77             values.add(value);
      78         }
      79         values = new ArrayList<>();
      80         headers.put(name, values);
      81     }
      82 
      83     /**
      84      * 返回门面类
      85      * @return RequestFacade
      86      */
      87     public HttpServletRequest getRequest() {
      88         return new HttpRequestFacade(this);
      89     }
      90 
      91     /**
      92      * 添加HTTP cookie
      93      * @param cookie http cookie
      94      */
      95     public void addCookie(Cookie cookie) {
      96         cookies.add(cookie);
      97     }
      98 
      99     /**
     100      * 解析HTTP Parameters,如果已经解析则返回。
     101      */
     102     public void parseParameters() {
     103         if (parameterPared) {
     104             return;
     105         }
     106         parameterMap = new ParameterMap<>();
     107         parameterMap.setLocked(false);
     108 
     109         // 解析Query String or Form data
     110 
     111         parameterMap.setLocked(true);
     112     }
     113 
     114     /**
     115      * 添加HTTP Parameter
     116      * @param name Http Parameter name
     117      * @param values Http Parameter values
     118      */
     119     public void addParameter(String name, String values[]) {
     120         parameterMap.put(name, values);
     121     }
     122 
     123 
     124     /**
     125      * Release all object references, and initialize instance variables, in
     126      * preparation for reuse of this object.
     127      * 清空所有数据
     128      */
     129     public void recycle() {
     130         headers.clear();
     131         cookies.clear();
     132         if (parameterMap != null) {
     133             parameterMap.setLocked(false);
     134             parameterMap.clear();
     135         }
     136         parameterPared = false;
     137         requestURI = null;
     138         input = null;
     139         attributes.clear();
     140     }
     141 
     142     //---------------------------some setter、getter methods
     143 
     144     public Connector getConnector() {
     145         return connector;
     146     }
     147 
     148     public void setConnector(Connector connector) {
     149         this.connector = connector;
     150     }
     151 
     152     public void setInput(InputStream input) {
     153         this.input = input;
     154     }
     155 
     156     public InputStream getInput() {
     157         return input;
     158     }
     159 
     160     public void setRequestURI(String requestURI) {
     161         this.requestURI = requestURI;
     162     }
     163 
     164     @Override
     165     public String getAuthType() {
     166         return null;
     167     }
     168 
     169     @Override
     170     public Cookie[] getCookies() {
     171         return new Cookie[0];
     172     }
     173 
     174     @Override
     175     public long getDateHeader(String name) {
     176         return 0;
     177     }
     178 
     179     @Override
     180     public String getHeader(String name) {
     181         return null;
     182     }
     183 
     184     @Override
     185     public Enumeration<String> getHeaders(String name) {
     186         return null;
     187     }
     188 
     189     @Override
     190     public Enumeration<String> getHeaderNames() {
     191         return null;
     192     }
     193 
     194     @Override
     195     public int getIntHeader(String name) {
     196         return 0;
     197     }
     198 
     199     @Override
     200     public String getMethod() {
     201         return null;
     202     }
     203 
     204     @Override
     205     public String getPathInfo() {
     206         return null;
     207     }
     208 
     209     @Override
     210     public String getPathTranslated() {
     211         return null;
     212     }
     213 
     214     @Override
     215     public String getContextPath() {
     216         return null;
     217     }
     218 
     219     @Override
     220     public String getQueryString() {
     221         return null;
     222     }
     223 
     224     @Override
     225     public String getRemoteUser() {
     226         return null;
     227     }
     228 
     229     @Override
     230     public boolean isUserInRole(String role) {
     231         return false;
     232     }
     233 
     234     @Override
     235     public Principal getUserPrincipal() {
     236         return null;
     237     }
     238 
     239     @Override
     240     public String getRequestedSessionId() {
     241         return null;
     242     }
     243 
     244     @Override
     245     public String getRequestURI() {
     246         return requestURI;
     247     }
     248 
     249     @Override
     250     public StringBuffer getRequestURL() {
     251         return null;
     252     }
     253 
     254     @Override
     255     public String getServletPath() {
     256         return null;
     257     }
     258 
     259     @Override
     260     public HttpSession getSession(boolean create) {
     261         return null;
     262     }
     263 
     264     @Override
     265     public HttpSession getSession() {
     266         return null;
     267     }
     268 
     269     @Override
     270     public String changeSessionId() {
     271         return null;
     272     }
     273 
     274     @Override
     275     public boolean isRequestedSessionIdValid() {
     276         return false;
     277     }
     278 
     279     @Override
     280     public boolean isRequestedSessionIdFromCookie() {
     281         return false;
     282     }
     283 
     284     @Override
     285     public boolean isRequestedSessionIdFromURL() {
     286         return false;
     287     }
     288 
     289     @Override
     290     public boolean isRequestedSessionIdFromUrl() {
     291         return false;
     292     }
     293 
     294     @Override
     295     public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
     296         return false;
     297     }
     298 
     299     @Override
     300     public void login(String username, String password) throws ServletException {
     301 
     302     }
     303 
     304     @Override
     305     public void logout() throws ServletException {
     306 
     307     }
     308 
     309     @Override
     310     public Collection<Part> getParts() throws IOException, ServletException {
     311         return null;
     312     }
     313 
     314     @Override
     315     public Part getPart(String name) throws IOException, ServletException {
     316         return null;
     317     }
     318 
     319     @Override
     320     public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {
     321         return null;
     322     }
     323 
     324     @Override
     325     public Object getAttribute(String name) {
     326         return null;
     327     }
     328 
     329     @Override
     330     public Enumeration<String> getAttributeNames() {
     331         return null;
     332     }
     333 
     334     @Override
     335     public String getCharacterEncoding() {
     336         return null;
     337     }
     338 
     339     @Override
     340     public void setCharacterEncoding(String env) throws UnsupportedEncodingException {
     341 
     342     }
     343 
     344     @Override
     345     public int getContentLength() {
     346         return 0;
     347     }
     348 
     349     @Override
     350     public long getContentLengthLong() {
     351         return 0;
     352     }
     353 
     354     @Override
     355     public String getContentType() {
     356         return null;
     357     }
     358 
     359     @Override
     360     public ServletInputStream getInputStream() throws IOException {
     361         return null;
     362     }
     363 
     364     @Override
     365     public String getParameter(String name) {
     366         parseParameters();
     367         return parameterMap.get(name)[0];
     368     }
     369 
     370     @Override
     371     public Enumeration<String> getParameterNames() {
     372         parseParameters();
     373         return new Enumerator<>(parameterMap.keySet());
     374     }
     375 
     376     @Override
     377     public String[] getParameterValues(String name) {
     378         parseParameters();
     379         return parameterMap.get(name);
     380     }
     381 
     382     @Override
     383     public Map<String, String[]> getParameterMap() {
     384         parseParameters();
     385         return parameterMap;
     386     }
     387 
     388     @Override
     389     public String getProtocol() {
     390         return null;
     391     }
     392 
     393     @Override
     394     public String getScheme() {
     395         return null;
     396     }
     397 
     398     @Override
     399     public String getServerName() {
     400         return null;
     401     }
     402 
     403     @Override
     404     public int getServerPort() {
     405         return 0;
     406     }
     407 
     408     @Override
     409     public BufferedReader getReader() throws IOException {
     410         return null;
     411     }
     412 
     413     @Override
     414     public String getRemoteAddr() {
     415         return null;
     416     }
     417 
     418     @Override
     419     public String getRemoteHost() {
     420         return null;
     421     }
     422 
     423     @Override
     424     public void setAttribute(String name, Object o) {
     425 
     426     }
     427 
     428     @Override
     429     public void removeAttribute(String name) {
     430 
     431     }
     432 
     433     @Override
     434     public Locale getLocale() {
     435         return null;
     436     }
     437 
     438     @Override
     439     public Enumeration<Locale> getLocales() {
     440         return null;
     441     }
     442 
     443     @Override
     444     public boolean isSecure() {
     445         return false;
     446     }
     447 
     448     @Override
     449     public RequestDispatcher getRequestDispatcher(String path) {
     450         return null;
     451     }
     452 
     453     @Override
     454     public String getRealPath(String path) {
     455         return null;
     456     }
     457 
     458     @Override
     459     public int getRemotePort() {
     460         return 0;
     461     }
     462 
     463     @Override
     464     public String getLocalName() {
     465         return null;
     466     }
     467 
     468     @Override
     469     public String getLocalAddr() {
     470         return null;
     471     }
     472 
     473     @Override
     474     public int getLocalPort() {
     475         return 0;
     476     }
     477 
     478     @Override
     479     public ServletContext getServletContext() {
     480         return null;
     481     }
     482 
     483     @Override
     484     public AsyncContext startAsync() throws IllegalStateException {
     485         return null;
     486     }
     487 
     488     @Override
     489     public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
     490         return null;
     491     }
     492 
     493     @Override
     494     public boolean isAsyncStarted() {
     495         return false;
     496     }
     497 
     498     @Override
     499     public boolean isAsyncSupported() {
     500         return false;
     501     }
     502 
     503     @Override
     504     public AsyncContext getAsyncContext() {
     505         return null;
     506     }
     507 
     508     @Override
     509     public DispatcherType getDispatcherType() {
     510         return null;
     511     }
     512 }
     513 
     514 package note2;
     515 
     516 import javax.servlet.ServletOutputStream;
     517 import javax.servlet.ServletResponse;
     518 import javax.servlet.http.Cookie;
     519 import javax.servlet.http.HttpServletResponse;
     520 import java.io.IOException;
     521 import java.io.OutputStream;
     522 import java.io.PrintWriter;
     523 import java.util.ArrayList;
     524 import java.util.Collection;
     525 import java.util.HashMap;
     526 import java.util.Locale;
     527 
     528 /**
     529  * Created by kanyuxia on 2017/4/26.
     530  * Http响应对象
     531  */
     532 public class HttpResponse implements HttpServletResponse {
     533     // ----------------------Some Response Information
     534     /**
     535      * 存放Http response headers
     536      */
     537     private HashMap<String, ArrayList<String>> headers = new HashMap<>();
     538 
     539     /**
     540      * 存放Http response cookies
     541      */
     542     private ArrayList<Cookie> cookies = new ArrayList<>();
     543     /**
     544      * The Connector through which this Response was received.
     545      */
     546     private Connector connector = null;
     547 
     548     private OutputStream output = null;
     549 
     550     private HttpRequest httpRequest = null;
     551 
     552     // ------------------some methods
     553 
     554     public void recycle() {
     555         headers.clear();
     556         cookies.clear();
     557         output = null;
     558         httpRequest = null;
     559     }
     560 
     561     public HttpServletResponse getResponse() {
     562         return new HttpResponseFacade(this);
     563     }
     564 
     565     // ------------------some setter、getter methods
     566     public Connector getConnector() {
     567         return connector;
     568     }
     569 
     570     public void setConnector(Connector connector) {
     571         this.connector = connector;
     572     }
     573 
     574     public void setOutput(OutputStream output) {
     575         this.output = output;
     576     }
     577 
     578     public HttpRequest getHttpRequest() {
     579         return httpRequest;
     580     }
     581 
     582     public void setHttpRequest(HttpRequest httpRequest) {
     583         this.httpRequest = httpRequest;
     584     }
     585 
     586     @Override
     587     public void addCookie(Cookie cookie) {
     588 
     589     }
     590 
     591     @Override
     592     public boolean containsHeader(String name) {
     593         return false;
     594     }
     595 
     596     @Override
     597     public String encodeURL(String url) {
     598         return null;
     599     }
     600 
     601     @Override
     602     public String encodeRedirectURL(String url) {
     603         return null;
     604     }
     605 
     606     @Override
     607     public String encodeUrl(String url) {
     608         return null;
     609     }
     610 
     611     @Override
     612     public String encodeRedirectUrl(String url) {
     613         return null;
     614     }
     615 
     616     @Override
     617     public void sendError(int sc, String msg) throws IOException {
     618 
     619     }
     620 
     621     @Override
     622     public void sendError(int sc) throws IOException {
     623 
     624     }
     625 
     626     @Override
     627     public void sendRedirect(String location) throws IOException {
     628 
     629     }
     630 
     631     @Override
     632     public void setDateHeader(String name, long date) {
     633 
     634     }
     635 
     636     @Override
     637     public void addDateHeader(String name, long date) {
     638 
     639     }
     640 
     641     @Override
     642     public void setHeader(String name, String value) {
     643 
     644     }
     645 
     646     @Override
     647     public void addHeader(String name, String value) {
     648 
     649     }
     650 
     651     @Override
     652     public void setIntHeader(String name, int value) {
     653 
     654     }
     655 
     656     @Override
     657     public void addIntHeader(String name, int value) {
     658 
     659     }
     660 
     661     @Override
     662     public void setStatus(int sc) {
     663 
     664     }
     665 
     666     @Override
     667     public void setStatus(int sc, String sm) {
     668 
     669     }
     670 
     671     @Override
     672     public int getStatus() {
     673         return 0;
     674     }
     675 
     676     @Override
     677     public String getHeader(String name) {
     678         return null;
     679     }
     680 
     681     @Override
     682     public Collection<String> getHeaders(String name) {
     683         return null;
     684     }
     685 
     686     @Override
     687     public Collection<String> getHeaderNames() {
     688         return null;
     689     }
     690 
     691     @Override
     692     public String getCharacterEncoding() {
     693         return null;
     694     }
     695 
     696     @Override
     697     public String getContentType() {
     698         return null;
     699     }
     700 
     701     @Override
     702     public ServletOutputStream getOutputStream() throws IOException {
     703         return null;
     704     }
     705 
     706     @Override
     707     public PrintWriter getWriter() throws IOException {
     708         return new PrintWriter(output);
     709     }
     710 
     711     @Override
     712     public void setCharacterEncoding(String charset) {
     713 
     714     }
     715 
     716     @Override
     717     public void setContentLength(int len) {
     718 
     719     }
     720 
     721     @Override
     722     public void setContentLengthLong(long len) {
     723 
     724     }
     725 
     726     @Override
     727     public void setContentType(String type) {
     728 
     729     }
     730 
     731     @Override
     732     public void setBufferSize(int size) {
     733 
     734     }
     735 
     736     @Override
     737     public int getBufferSize() {
     738         return 0;
     739     }
     740 
     741     @Override
     742     public void flushBuffer() throws IOException {
     743 
     744     }
     745 
     746     @Override
     747     public void resetBuffer() {
     748 
     749     }
     750 
     751     @Override
     752     public boolean isCommitted() {
     753         return false;
     754     }
     755 
     756     @Override
     757     public void reset() {
     758 
     759     }
     760 
     761     @Override
     762     public void setLocale(Locale loc) {
     763 
     764     }
     765 
     766     @Override
     767     public Locale getLocale() {
     768         return null;
     769     }
     770 }
     771 
     772 package note2;
     773 
     774 import javax.servlet.*;
     775 import javax.servlet.http.*;
     776 import java.io.BufferedReader;
     777 import java.io.IOException;
     778 import java.io.UnsupportedEncodingException;
     779 import java.security.Principal;
     780 import java.util.Collection;
     781 import java.util.Enumeration;
     782 import java.util.Locale;
     783 import java.util.Map;
     784 
     785 /**
     786  * Created by kanyuxia on 2017/5/3.
     787  */
     788 public class HttpRequestFacade implements HttpServletRequest {
     789 
     790     private HttpServletRequest httpServletRequest;
     791 
     792     HttpRequestFacade(HttpServletRequest httpServletRequest) {
     793         this.httpServletRequest = httpServletRequest;
     794     }
     795 
     796     @Override
     797     public Object getAttribute(String name) {
     798         return httpServletRequest.getAttribute(name);
     799     }
     800 
     801     @Override
     802     public Enumeration<String> getAttributeNames() {
     803         return httpServletRequest.getAttributeNames();
     804     }
     805 
     806     @Override
     807     public String getCharacterEncoding() {
     808         return httpServletRequest.getCharacterEncoding();
     809     }
     810 
     811     @Override
     812     public void setCharacterEncoding(String env) throws UnsupportedEncodingException {
     813         httpServletRequest.setCharacterEncoding(env);
     814     }
     815 
     816     @Override
     817     public int getContentLength() {
     818         return httpServletRequest.getContentLength();
     819     }
     820 
     821     @Override
     822     public long getContentLengthLong() {
     823         return httpServletRequest.getContentLengthLong();
     824     }
     825 
     826     @Override
     827     public String getContentType() {
     828         return httpServletRequest.getContentType();
     829     }
     830 
     831     @Override
     832     public ServletInputStream getInputStream() throws IOException {
     833         return httpServletRequest.getInputStream();
     834     }
     835 
     836     @Override
     837     public String getParameter(String name) {
     838         return httpServletRequest.getParameter(name);
     839     }
     840 
     841     @Override
     842     public Enumeration<String> getParameterNames() {
     843         return httpServletRequest.getParameterNames();
     844     }
     845 
     846     @Override
     847     public String[] getParameterValues(String name) {
     848         return httpServletRequest.getParameterValues(name);
     849     }
     850 
     851     @Override
     852     public Map<String, String[]> getParameterMap() {
     853         return httpServletRequest.getParameterMap();
     854     }
     855 
     856     @Override
     857     public String getProtocol() {
     858         return httpServletRequest.getProtocol();
     859     }
     860 
     861     @Override
     862     public String getScheme() {
     863         return httpServletRequest.getScheme();
     864     }
     865 
     866     @Override
     867     public String getServerName() {
     868         return httpServletRequest.getServerName();
     869     }
     870 
     871     @Override
     872     public int getServerPort() {
     873         return httpServletRequest.getServerPort();
     874     }
     875 
     876     @Override
     877     public BufferedReader getReader() throws IOException {
     878         return httpServletRequest.getReader();
     879     }
     880 
     881     @Override
     882     public String getRemoteAddr() {
     883         return httpServletRequest.getRemoteAddr();
     884     }
     885 
     886     @Override
     887     public String getRemoteHost() {
     888         return httpServletRequest.getRemoteHost();
     889     }
     890 
     891     @Override
     892     public void setAttribute(String name, Object o) {
     893         httpServletRequest.setAttribute(name, o);
     894     }
     895 
     896     @Override
     897     public void removeAttribute(String name) {
     898         httpServletRequest.removeAttribute(name);
     899     }
     900 
     901     @Override
     902     public Locale getLocale() {
     903         return httpServletRequest.getLocale();
     904     }
     905 
     906     @Override
     907     public Enumeration<Locale> getLocales() {
     908         return httpServletRequest.getLocales();
     909     }
     910 
     911     @Override
     912     public boolean isSecure() {
     913         return httpServletRequest.isSecure();
     914     }
     915 
     916     @Override
     917     public RequestDispatcher getRequestDispatcher(String path) {
     918         return httpServletRequest.getRequestDispatcher(path);
     919     }
     920 
     921     @Override
     922     public String getRealPath(String path) {
     923         return httpServletRequest.getRealPath(path);
     924     }
     925 
     926     @Override
     927     public int getRemotePort() {
     928         return httpServletRequest.getRemotePort();
     929     }
     930 
     931     @Override
     932     public String getLocalName() {
     933         return httpServletRequest.getLocalName();
     934     }
     935 
     936     @Override
     937     public String getLocalAddr() {
     938         return httpServletRequest.getLocalAddr();
     939     }
     940 
     941     @Override
     942     public int getLocalPort() {
     943         return httpServletRequest.getLocalPort();
     944     }
     945 
     946     @Override
     947     public ServletContext getServletContext() {
     948         return httpServletRequest.getServletContext();
     949     }
     950 
     951     @Override
     952     public AsyncContext startAsync() throws IllegalStateException {
     953         return httpServletRequest.startAsync();
     954     }
     955 
     956     @Override
     957     public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
     958         return servletRequest.startAsync();
     959     }
     960 
     961     @Override
     962     public boolean isAsyncStarted() {
     963         return httpServletRequest.isAsyncStarted();
     964     }
     965 
     966     @Override
     967     public boolean isAsyncSupported() {
     968         return httpServletRequest.isAsyncSupported();
     969     }
     970 
     971     @Override
     972     public AsyncContext getAsyncContext() {
     973         return httpServletRequest.getAsyncContext();
     974     }
     975 
     976     @Override
     977     public DispatcherType getDispatcherType() {
     978         return httpServletRequest.getDispatcherType();
     979     }
     980 
     981     @Override
     982     public String getAuthType() {
     983         return httpServletRequest.getAuthType();
     984     }
     985 
     986     @Override
     987     public Cookie[] getCookies() {
     988         return httpServletRequest.getCookies();
     989     }
     990 
     991     @Override
     992     public long getDateHeader(String name) {
     993         return httpServletRequest.getDateHeader(name);
     994     }
     995 
     996     @Override
     997     public String getHeader(String name) {
     998         return httpServletRequest.getHeader(name);
     999     }
    1000 
    1001     @Override
    1002     public Enumeration<String> getHeaders(String name) {
    1003         return httpServletRequest.getHeaders(name);
    1004     }
    1005 
    1006     @Override
    1007     public Enumeration<String> getHeaderNames() {
    1008         return httpServletRequest.getHeaderNames();
    1009     }
    1010 
    1011     @Override
    1012     public int getIntHeader(String name) {
    1013         return httpServletRequest.getIntHeader(name);
    1014     }
    1015 
    1016     @Override
    1017     public String getMethod() {
    1018         return httpServletRequest.getMethod();
    1019     }
    1020 
    1021     @Override
    1022     public String getPathInfo() {
    1023         return httpServletRequest.getPathInfo();
    1024     }
    1025 
    1026     @Override
    1027     public String getPathTranslated() {
    1028         return httpServletRequest.getPathTranslated();
    1029     }
    1030 
    1031     @Override
    1032     public String getContextPath() {
    1033         return httpServletRequest.getContextPath();
    1034     }
    1035 
    1036     @Override
    1037     public String getQueryString() {
    1038         return httpServletRequest.getQueryString();
    1039     }
    1040 
    1041     @Override
    1042     public String getRemoteUser() {
    1043         return httpServletRequest.getRemoteUser();
    1044     }
    1045 
    1046     @Override
    1047     public boolean isUserInRole(String role) {
    1048         return httpServletRequest.isUserInRole(role);
    1049     }
    1050 
    1051     @Override
    1052     public Principal getUserPrincipal() {
    1053         return httpServletRequest.getUserPrincipal();
    1054     }
    1055 
    1056     @Override
    1057     public String getRequestedSessionId() {
    1058         return httpServletRequest.getRequestedSessionId();
    1059     }
    1060 
    1061     @Override
    1062     public String getRequestURI() {
    1063         return httpServletRequest.getRequestURI();
    1064     }
    1065 
    1066     @Override
    1067     public StringBuffer getRequestURL() {
    1068         return httpServletRequest.getRequestURL();
    1069     }
    1070 
    1071     @Override
    1072     public String getServletPath() {
    1073         return httpServletRequest.getServletPath();
    1074     }
    1075 
    1076     @Override
    1077     public HttpSession getSession(boolean create) {
    1078         return httpServletRequest.getSession();
    1079     }
    1080 
    1081     @Override
    1082     public HttpSession getSession() {
    1083         return httpServletRequest.getSession();
    1084     }
    1085 
    1086     @Override
    1087     public String changeSessionId() {
    1088         return httpServletRequest.changeSessionId();
    1089     }
    1090 
    1091     @Override
    1092     public boolean isRequestedSessionIdValid() {
    1093         return httpServletRequest.isRequestedSessionIdValid();
    1094     }
    1095 
    1096     @Override
    1097     public boolean isRequestedSessionIdFromCookie() {
    1098         return httpServletRequest.isRequestedSessionIdFromCookie();
    1099     }
    1100 
    1101     @Override
    1102     public boolean isRequestedSessionIdFromURL() {
    1103         return httpServletRequest.isRequestedSessionIdFromURL();
    1104     }
    1105 
    1106     @Override
    1107     public boolean isRequestedSessionIdFromUrl() {
    1108         return httpServletRequest.isRequestedSessionIdFromUrl();
    1109     }
    1110 
    1111     @Override
    1112     public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
    1113         return httpServletRequest.authenticate(response);
    1114     }
    1115 
    1116     @Override
    1117     public void login(String username, String password) throws ServletException {
    1118         httpServletRequest.login(username, password);
    1119     }
    1120 
    1121     @Override
    1122     public void logout() throws ServletException {
    1123         httpServletRequest.logout();
    1124     }
    1125 
    1126     @Override
    1127     public Collection<Part> getParts() throws IOException, ServletException {
    1128         return httpServletRequest.getParts();
    1129     }
    1130 
    1131     @Override
    1132     public Part getPart(String name) throws IOException, ServletException {
    1133         return httpServletRequest.getPart(name);
    1134     }
    1135 
    1136     @Override
    1137     public <T extends HttpUpgradeHandler> T upgrade(Class<T> handlerClass) throws IOException, ServletException {
    1138         return httpServletRequest.upgrade(handlerClass);
    1139     }
    1140 }
    1141 
    1142 package note2;
    1143 
    1144 import javax.servlet.ServletOutputStream;
    1145 import javax.servlet.http.Cookie;
    1146 import javax.servlet.http.HttpServletResponse;
    1147 import java.io.IOException;
    1148 import java.io.PrintWriter;
    1149 import java.util.Collection;
    1150 import java.util.Locale;
    1151 
    1152 /**
    1153  * Created by kanyuxia on 2017/5/3.
    1154  */
    1155 public class HttpResponseFacade implements HttpServletResponse {
    1156     private HttpServletResponse httpServletResponse;
    1157 
    1158     HttpResponseFacade(HttpServletResponse httpServletResponse) {
    1159         this.httpServletResponse = httpServletResponse;
    1160     }
    1161     @Override
    1162     public String getCharacterEncoding() {
    1163         return httpServletResponse.getCharacterEncoding();
    1164     }
    1165 
    1166     @Override
    1167     public String getContentType() {
    1168         return httpServletResponse.getContentType();
    1169     }
    1170 
    1171     @Override
    1172     public ServletOutputStream getOutputStream() throws IOException {
    1173         return httpServletResponse.getOutputStream();
    1174     }
    1175 
    1176     @Override
    1177     public PrintWriter getWriter() throws IOException {
    1178         return httpServletResponse.getWriter();
    1179     }
    1180 
    1181     @Override
    1182     public void setCharacterEncoding(String charset) {
    1183         httpServletResponse.setCharacterEncoding(charset);
    1184     }
    1185 
    1186     @Override
    1187     public void setContentLength(int len) {
    1188         httpServletResponse.setContentLength(len);
    1189     }
    1190 
    1191     @Override
    1192     public void setContentLengthLong(long len) {
    1193         httpServletResponse.setContentLengthLong(len);
    1194     }
    1195 
    1196     @Override
    1197     public void setContentType(String type) {
    1198         httpServletResponse.setContentType(type);
    1199     }
    1200 
    1201     @Override
    1202     public void setBufferSize(int size) {
    1203         httpServletResponse.setBufferSize(size);
    1204     }
    1205 
    1206     @Override
    1207     public int getBufferSize() {
    1208         return httpServletResponse.getBufferSize();
    1209     }
    1210 
    1211     @Override
    1212     public void flushBuffer() throws IOException {
    1213         httpServletResponse.flushBuffer();
    1214     }
    1215 
    1216     @Override
    1217     public void resetBuffer() {
    1218         httpServletResponse.resetBuffer();
    1219     }
    1220 
    1221     @Override
    1222     public boolean isCommitted() {
    1223         return httpServletResponse.isCommitted();
    1224     }
    1225 
    1226     @Override
    1227     public void reset() {
    1228         httpServletResponse.reset();
    1229     }
    1230 
    1231     @Override
    1232     public void setLocale(Locale loc) {
    1233         httpServletResponse.setLocale(loc);
    1234     }
    1235 
    1236     @Override
    1237     public Locale getLocale() {
    1238         return httpServletResponse.getLocale();
    1239     }
    1240 
    1241     @Override
    1242     public void addCookie(Cookie cookie) {
    1243         httpServletResponse.addCookie(cookie);
    1244     }
    1245 
    1246     @Override
    1247     public boolean containsHeader(String name) {
    1248         return httpServletResponse.containsHeader(name);
    1249     }
    1250 
    1251     @Override
    1252     public String encodeURL(String url) {
    1253         return httpServletResponse.encodeURL(url);
    1254     }
    1255 
    1256     @Override
    1257     public String encodeRedirectURL(String url) {
    1258         return httpServletResponse.encodeRedirectURL(url);
    1259     }
    1260 
    1261     @Override
    1262     public String encodeUrl(String url) {
    1263         return httpServletResponse.encodeUrl(url);
    1264     }
    1265 
    1266     @Override
    1267     public String encodeRedirectUrl(String url) {
    1268         return httpServletResponse.encodeRedirectURL(url);
    1269     }
    1270 
    1271     @Override
    1272     public void sendError(int sc, String msg) throws IOException {
    1273         httpServletResponse.sendError(sc, msg);
    1274     }
    1275 
    1276     @Override
    1277     public void sendError(int sc) throws IOException {
    1278         httpServletResponse.sendError(sc);
    1279     }
    1280 
    1281     @Override
    1282     public void sendRedirect(String location) throws IOException {
    1283         httpServletResponse.sendRedirect(location);
    1284     }
    1285 
    1286     @Override
    1287     public void setDateHeader(String name, long date) {
    1288         httpServletResponse.setDateHeader(name, date);
    1289     }
    1290 
    1291     @Override
    1292     public void addDateHeader(String name, long date) {
    1293         httpServletResponse.addDateHeader(name, date);
    1294     }
    1295 
    1296     @Override
    1297     public void setHeader(String name, String value) {
    1298         httpServletResponse.setHeader(name, value);
    1299     }
    1300 
    1301     @Override
    1302     public void addHeader(String name, String value) {
    1303         httpServletResponse.addHeader(name, value);
    1304     }
    1305 
    1306     @Override
    1307     public void setIntHeader(String name, int value) {
    1308         httpServletResponse.setIntHeader(name, value);
    1309     }
    1310 
    1311     @Override
    1312     public void addIntHeader(String name, int value) {
    1313         httpServletResponse.addIntHeader(name, value);
    1314     }
    1315 
    1316     @Override
    1317     public void setStatus(int sc) {
    1318         httpServletResponse.setStatus(sc);
    1319     }
    1320 
    1321     @Override
    1322     public void setStatus(int sc, String sm) {
    1323         httpServletResponse.setStatus(sc, sm);
    1324     }
    1325 
    1326     @Override
    1327     public int getStatus() {
    1328         return httpServletResponse.getStatus();
    1329     }
    1330 
    1331     @Override
    1332     public String getHeader(String name) {
    1333         return httpServletResponse.getHeader(name);
    1334     }
    1335 
    1336     @Override
    1337     public Collection<String> getHeaders(String name) {
    1338         return httpServletResponse.getHeaders(name);
    1339     }
    1340 
    1341     @Override
    1342     public Collection<String> getHeaderNames() {
    1343         return httpServletResponse.getHeaderNames();
    1344     }
    1345 }
    View Code

    工具类:

      1 package note2;
      2 
      3 import java.util.Collection;
      4 import java.util.Enumeration;
      5 import java.util.Iterator;
      6 import java.util.Map;
      7 
      8 /**
      9  * Created by kanyuxia on 2017/4/27.
     10  */
     11 public class Enumerator<E> implements Enumeration<E> {
     12     private Iterator<E> iterator = null;
     13 
     14     public Enumerator(Collection<E> collection) {
     15         this(collection.iterator());
     16     }
     17 
     18     public Enumerator(Iterator<E> iterator) {
     19         super();
     20         this.iterator = iterator;
     21     }
     22 
     23     public Enumerator(Map<?, E> map) {
     24         this(map.values().iterator());
     25     }
     26 
     27     @Override
     28     public boolean hasMoreElements() {
     29         return iterator.hasNext();
     30     }
     31 
     32     @Override
     33     public E nextElement() {
     34         return (E) iterator.next();
     35     }
     36 }
     37 
     38 
     39 package note2;
     40 
     41 import java.util.HashMap;
     42 import java.util.Map;
     43 
     44 /**
     45  * Extended implementation of <strong>HashMap</strong> that includes a
     46  * <code>locked</code> property.  This class can be used to safely expose
     47  * Catalina internal parameter map objects to user classes without having
     48  * to clone them in order to avoid modifications.  When first created, a
     49  * <code>ParmaeterMap</code> instance is not locked.
     50  *
     51  * 存放Http参数:Query String or Form Data
     52  * Created by kanyuxia on 2017/4/27.
     53  */
     54 public class ParameterMap<K, V> extends HashMap<K, V> {
     55     private static final long serialVersionUID = -7752723814131658494L;
     56 
     57     /**
     58      * 一些构造函数
     59      */
     60     public ParameterMap() {
     61         super();
     62     }
     63 
     64     public ParameterMap(int initialCapacity) {
     65         super(initialCapacity);
     66     }
     67 
     68     public ParameterMap(int initialCapaticity, float loadFactory) {
     69         super(initialCapaticity, loadFactory);
     70     }
     71 
     72     public ParameterMap(Map<K, V> map) {
     73         super(map);
     74     }
     75 
     76     /**
     77      * The current lock state of this parameter map.
     78      * ParameterMap是否锁住。
     79      */
     80     private boolean locked = false;
     81 
     82     public boolean isLocked() {
     83         return locked;
     84     }
     85 
     86     public void setLocked(boolean locked) {
     87         this.locked = locked;
     88     }
     89 
     90     @Override
     91     public void clear() {
     92         if (locked) {
     93             throw new IllegalStateException("parameterMap.locked");
     94         }
     95         super.clear();
     96     }
     97 
     98     @Override
     99     public V put(K key, V value) {
    100         if (locked) {
    101             throw new IllegalStateException("parameterMap.locked");
    102         }
    103         return super.put(key, value);
    104     }
    105 
    106     @Override
    107     public void putAll(Map<? extends K, ? extends V> m) {
    108         if (locked) {
    109             throw new IllegalStateException("parameterMap.locked");
    110         }
    111         super.putAll(m);
    112     }
    113 
    114     @Override
    115     public boolean remove(Object key, Object value) {
    116         if (locked) {
    117             throw new IllegalStateException("parameterMap.locked");
    118         }
    119         return super.remove(key, value);
    120     }
    121 }
    View Code

    HttpConnector类:

      1 package note2;
      2 
      3 import javax.servlet.http.HttpServletRequest;
      4 import javax.servlet.http.HttpServletResponse;
      5 import java.io.IOException;
      6 import java.net.ServerSocket;
      7 import java.net.Socket;
      8 import java.util.Stack;
      9 import java.util.Vector;
     10 
     11 /**
     12  * Created by kanyuxia on 2017/4/26.
     13  * Http连接器。
     14  */
     15 public class HttpConnector implements Runnable,Connector {
     16     /**
     17      * The Container used for processing requests received by this Connector.
     18      * Servlet容器
     19      */
     20     private Container container = null;
     21 
     22     /**
     23      * The current number of processors that have been created.
     24      * 当前已经创建的HttpProcessor
     25      */
     26     private int curProcessors = 0;
     27 
     28     /**
     29      * The minimum number of processors to start at initialization time.
     30      * HttpProcessor对象池最小对象数
     31      */
     32     private int minProcessors = 5;
     33 
     34     /**
     35      * The maximum number of processors allowed, or <0 for unlimited.
     36      * HttpProcessor对象池最大对象数
     37      */
     38     private int maxProcessors = 20;
     39 
     40     /**
     41      * The port number on which we listen for HTTP requests.
     42      * 服务器端口号
     43      */
     44     private int port = 10086;
     45 
     46     /**
     47      * The set of processors that have been created but are not currently
     48      * being used to process a request.
     49      * 存放已经创建但未被使用的Http处理器对象
     50      */
     51     private final Stack<HttpProcessor> processors = new Stack<>();
     52 
     53     /**
     54      * The set of processors that have ever been created.
     55      * 存放已经创建的Http处理器
     56      */
     57     private Vector<HttpProcessor> created = new Vector<>();
     58 
     59     /**
     60      * The request scheme that will be set on all requests received
     61      * through this connector.
     62      * 服务器处理请求模式(协议)
     63      */
     64     private String scheme = "http";
     65 
     66     /**
     67      * The server socket through which we listen for incoming TCP connections.
     68      * 服务器ServerSocket
     69      */
     70     private ServerSocket serverSocket = null;
     71 
     72     /**
     73      * The background thread that listens for incoming TCP/IP connections and
     74      * hands them off to an appropriate processor.
     75      * 启动Http连接器,监听Http请求,把socket分发给HttpProcessor进行处理。
     76      */
     77     public void run() {
     78         while (true) {
     79             Socket socket = null;
     80             try {
     81                 socket = serverSocket.accept();
     82             } catch (IOException e) {
     83                 e.printStackTrace();
     84             }
     85             HttpProcessor processor = createProcessor();
     86             if (processor != null) {
     87                 processor.assign(socket);
     88             }
     89         }
     90     }
     91 
     92     /**
     93      * Create (or allocate) and return an available processor for use in
     94      * processing a specific HTTP request, if possible.  If the maximum
     95      * allowed processors have already been created and are in use, return
     96      * <code>null</code> instead.
     97      * 创建HttpProcessor:1. 从栈中拿 2. new一个 3. 返回null
     98      */
     99     public HttpProcessor createProcessor() {
    100         synchronized (processors) {
    101             if (processors.size() > 0) {
    102                 return processors.pop();
    103             }
    104             if (maxProcessors > 0 && curProcessors < maxProcessors) {
    105                 return newProcessor();
    106             } else {
    107                 if (maxProcessors < 0) {
    108                     return newProcessor();
    109                 }
    110                 return null;
    111             }
    112         }
    113     }
    114 
    115     /**
    116      * Initialize this connector (create ServerSocket here!)
    117      * 创建ServerSocket,在原HttpConnector中使用ServerSocketFactory创建,这里就直接创建
    118      */
    119     public void initialize() {
    120         try {
    121             serverSocket = new ServerSocket(port);
    122         } catch (IOException e) {
    123             e.printStackTrace();
    124         }
    125     }
    126 
    127     /**
    128      * Begin processing requests via this Connector.
    129      * 启动Http连接器,并创建HttpProcessor线程对象池
    130      */
    131     public void start() {
    132         // 启动Http连接器
    133         Thread thread = new Thread(this);
    134         thread.setDaemon(true);
    135         thread.start();
    136         // 创建最小HttpProcessor线程对象池
    137         while (curProcessors < minProcessors) {
    138             if (maxProcessors > 0 && curProcessors >= maxProcessors) {
    139                 break;
    140             }
    141             HttpProcessor processor = newProcessor();
    142             recycle(processor);
    143         }
    144     }
    145 
    146     /**
    147      * Create and return a new processor suitable for processing HTTP
    148      * requests and returning the corresponding responses.
    149      * 创建HttpProcessor对象,并使用运行它(它运行在一个单独的后台线程中)
    150      */
    151     private HttpProcessor newProcessor() {
    152         HttpProcessor processor = new HttpProcessor(this, curProcessors++);
    153         created.addElement(processor);
    154         processor.start();
    155         return processor;
    156     }
    157 
    158     /**
    159      * Recycle the specified Processor so that it can be used again.
    160      * 回收已经没有使用的HttpProcessor
    161      * @param processor The processor to be recycled
    162      */
    163     void recycle(HttpProcessor processor) {
    164         processors.push(processor);
    165     }
    166 
    167     @Override
    168     public HttpServletRequest createRequest() {
    169         HttpRequest httpRequest = new HttpRequest();
    170         httpRequest.setConnector(this);
    171         return httpRequest;
    172     }
    173 
    174     @Override
    175     public HttpServletResponse createResponse() {
    176         HttpResponse httpResponse = new HttpResponse();
    177         httpResponse.setConnector(this);
    178         return httpResponse;
    179     }
    180 
    181     @Override
    182     public Container getContainer() {
    183         return container;
    184     }
    185 
    186     @Override
    187     public void setContainer(Container container) {
    188         this.container = container;
    189     }
    190 
    191     @Override
    192     public String getScheme() {
    193         return scheme;
    194     }
    195 
    196     @Override
    197     public void setScheme(String scheme) {
    198         this.scheme = scheme;
    199     }
    200 
    201     public void setMaxProcessors(int maxProcessors) {
    202         this.maxProcessors = maxProcessors;
    203     }
    204 
    205     public int getMaxProcessors() {
    206         return maxProcessors;
    207     }
    208 
    209     public void setMinProcessors(int minProcessors) {
    210         this.minProcessors = minProcessors;
    211     }
    212 
    213     public int getMinProcessors() {
    214         return minProcessors;
    215     }
    216 
    217     public int getPort() {
    218         return port;
    219     }
    220 
    221     public void setPort(int port) {
    222         this.port = port;
    223     }
    224 }
    View Code

    HttpProcessor类:

      1 package note2;
      2 
      3 import javax.servlet.ServletException;
      4 import java.io.*;
      5 import java.net.Socket;
      6 
      7 /**
      8  * Created by kanyuxia on 2017/4/26.
      9  * Http处理器
     10  */
     11 public class HttpProcessor implements Runnable {
     12 
     13     /**
     14      * The HttpConnector with which this processor is associated.
     15      */
     16     private HttpConnector connector = null;
     17 
     18     /**
     19      * Is there a new socket available?
     20      * 是否有新的socket可用
     21      */
     22     private boolean available = false;
     23 
     24     /**
     25      * The socket we are currently processing a request for.  This object
     26      * is used for inter-thread communication only.
     27      */
     28     private Socket socket = null;
     29 
     30     /**
     31      * The identifier of this processor, unique per connector.
     32      */
     33     private int id = 0;
     34 
     35     /**
     36      * The HTTP request object we will pass to our associated container.
     37      */
     38     private HttpRequest httpRequest = null;
     39 
     40     /**
     41      * The HTTP response object we will pass to our associated container.
     42      */
     43     private HttpResponse httpResponse = null;
     44 
     45 
     46     /**
     47      * Construct a new HttpProcessor associated with the specified connector.
     48      *
     49      * @param connector HttpConnector that owns this processor
     50      * @param id Identifier of this HttpProcessor (unique per connector)
     51      */
     52     public HttpProcessor(HttpConnector connector, int id) {
     53         this.connector = connector;
     54         this.id = id;
     55         this.httpRequest = (HttpRequest) connector.createRequest();
     56         this.httpResponse = (HttpResponse) connector.createResponse();
     57     }
     58 
     59 
     60     /**
     61      * Start the background thread we will use for request processing.
     62      * 启动一个后台线程运行HttpProcessor
     63      */
     64     public void start() {
     65         Thread thread = new Thread(this);
     66         thread.setDaemon(true);
     67         thread.start();
     68     }
     69 
     70 
     71     /**
     72      * The background thread that listens for incoming TCP/IP connections and
     73      * hands them off to an appropriate processor.
     74      * 等待HttpConnector分配socket,然后处理该scoket,最后通知HttpConnector回收该HttpProcessor
     75      */
     76     public void run() {
     77         while (true) {
     78             // Wait for the next socket to be assigned
     79             Socket socket = await();
     80             if (socket == null) {
     81                 continue;
     82             }
     83             System.out.println(Thread.currentThread().getName());
     84             // Process the request from this socket
     85             process(socket);
     86 
     87             // Finish up this request
     88             connector.recycle(this);
     89         }
     90     }
     91 
     92     /**
     93      * Process an incoming HTTP request on the Socket that has been assigned
     94      * to this Processor.  Any exceptions that occur during processing must be
     95      * swallowed and dealt with.
     96      * 处理HttpConector分配的socket:1. 解析请求  2. 处理请求(调用容器处理)
     97      * @param socket The socket on which we are connected to the client
     98      */
     99     private void process(Socket socket) {
    100         InputStream input = null;
    101         OutputStream output = null;
    102         try {
    103             input = socket.getInputStream();
    104             output = socket.getOutputStream();
    105         } catch (IOException e) {
    106             e.printStackTrace();
    107         }
    108         httpRequest.setInput(input);
    109         httpResponse.setOutput(output);
    110         httpResponse.setHttpRequest(httpRequest);
    111         // Parse the incoming request
    112         parseConnection(socket);
    113         parseRequest(input, output);
    114         parseHeader(input, output);
    115 
    116         // Ask our Container to process this request
    117         try {
    118             connector.getContainer().invoke(httpRequest, httpResponse);
    119         } catch (IOException e) {
    120             e.printStackTrace();
    121         } catch (ServletException e) {
    122             e.printStackTrace();
    123         }
    124 
    125         //
    126         httpRequest.recycle();
    127         httpResponse.recycle();
    128     }
    129 
    130     /**
    131      * Parse and record the connection parameters related to this request.
    132      * 解析连接
    133      * @param socket The socket on which we are connected
    134      */
    135     private void parseConnection(Socket socket) {
    136     }
    137 
    138     /**
    139      * Parse the incoming HTTP request and set the corresponding HTTP request
    140      * properties.
    141      * 解析请求行
    142      * @param input The input stream attached to our socket
    143      * @param output The output stream of the socket
    144      */
    145     private void parseRequest(InputStream input, OutputStream output) {
    146         // 在这里仅仅解析了requestURI
    147         BufferedInputStream inputStream = new BufferedInputStream(input);
    148         StringBuilder stringBuilder = new StringBuilder(1024);
    149         byte[] buffer = new byte[1024];
    150         int b = 0;
    151         try {
    152             b = inputStream.read(buffer);
    153         } catch (IOException e) {
    154             e.printStackTrace();
    155         }
    156         for (int i = 0; i < b; i++) {
    157             stringBuilder.append((char) buffer[i]);
    158         }
    159         int begin = stringBuilder.indexOf(" ") + 1;
    160         int end = stringBuilder.indexOf(" ", begin);
    161         String requestURI = stringBuilder.substring(begin, end);
    162         httpRequest.setRequestURI(requestURI);
    163     }
    164 
    165     /**
    166      * Parse the incoming HTTP request headers, and set the appropriate
    167      * request headers.
    168      * 解析请求头
    169      * @param input The input stream connected to our socket
    170      */
    171     private void parseHeader(InputStream input, OutputStream output) {
    172 
    173     }
    174 
    175     /**
    176      * Process an incoming TCP/IP connection on the specified socket.  Any
    177      * exception that occurs during processing must be logged and swallowed.
    178      * <b>NOTE</b>:  This method is called from our Connector's thread.  We
    179      * must assign it to our own thread so that multiple simultaneous
    180      * requests can be handled.
    181      * HttpConnector分配一个新的socket
    182      * @param socket TCP socket to process
    183      */
    184     public void assign(Socket socket) {
    185         synchronized (this) {
    186             // Wait for the Processor to get the previous Socket
    187             while (available) {
    188                 try {
    189                     wait();
    190                 } catch (InterruptedException e) {
    191                     e.printStackTrace();
    192                 }
    193             }
    194 
    195             // Store the newly available Socket and notify our thread
    196             this.socket = socket;
    197             available = true;
    198             notifyAll();
    199         }
    200     }
    201 
    202     /**
    203      * Await a newly assigned Socket from our Connector, or <code>null</code>
    204      * if we are supposed to shut down.
    205      * 等待HttpConenctor分配一个新的socket
    206      */
    207     private Socket await() {
    208         synchronized (this) {
    209             // Wait for the Connector to provide a new Socket
    210             while (!available) {
    211                 try {
    212                     wait();
    213                 } catch (InterruptedException e) {
    214                     e.printStackTrace();
    215                 }
    216             }
    217 
    218             // Notify the Connector that we have received this Socket
    219             available = false;
    220             notifyAll();
    221             return socket;
    222         }
    223     }
    224 }
    View Code

    SimpleContainer类:

     1 package note2;
     2 
     3 import note1.HttpServer;
     4 
     5 import javax.servlet.Servlet;
     6 import javax.servlet.ServletException;
     7 import java.io.File;
     8 import java.io.IOException;
     9 import java.net.URL;
    10 import java.net.URLClassLoader;
    11 import java.net.URLStreamHandler;
    12 
    13 /**
    14  * Created by kanyuxia on 2017/5/3.
    15  */
    16 public class SimpleContainer implements Container {
    17 
    18     @SuppressWarnings("unchecked")
    19     public void invoke(HttpRequest request, HttpResponse response) throws IOException, ServletException {
    20         String servletName = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/") + 1);
    21         // 创建URLClassLoader
    22         URLClassLoader classLoader = null;
    23         try {
    24             // 创建URL
    25             URL[] urls = new URL[1];
    26             File classPath = new File(HttpServer.SERVLET_ROOT);
    27             String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString();
    28             URLStreamHandler streamHandler = null;
    29             urls[0] = new URL(null, repository, streamHandler);
    30             classLoader = new URLClassLoader(urls);
    31         } catch (IOException e) {
    32             System.out.println();
    33         }
    34         Class<Servlet> servletClass = null;
    35         try {
    36             servletClass = (Class<Servlet>) classLoader.loadClass(servletName);
    37         } catch (ClassNotFoundException e) {
    38             e.printStackTrace();
    39         }
    40         Servlet servlet = null;
    41         try {
    42             servlet = servletClass.newInstance();
    43         } catch (InstantiationException e) {
    44             e.printStackTrace();
    45         } catch (IllegalAccessException e) {
    46             e.printStackTrace();
    47         }
    48         servlet.service(request.getRequest(), response.getResponse());
    49     }
    50 }
    View Code

    BootStrap启动类:

     1 package note2;
     2 
     3 /**
     4  * Created by kanyuxia on 2017/5/3.
     5  */
     6 public class BootStrap {
     7     public static void main(String[] args) {
     8         HttpConnector httpConnector = new HttpConnector();
     9         httpConnector.setContainer(new SimpleContainer());
    10         httpConnector.initialize();
    11         httpConnector.start();
    12     }
    13 }
    View Code
  • 相关阅读:
    Java实现各种内部排序算法
    Java实现堆排序(大根堆)
    Java对象的序列化和反序列化
    Java实现链式存储的二叉查找树(递归方法)
    337. House Robber III(包含I和II)
    318. Maximum Product of Word Lengths
    114. Flatten Binary Tree to Linked List
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    96. Unique Binary Search Trees(I 和 II)
  • 原文地址:https://www.cnblogs.com/maying3010/p/6821406.html
Copyright © 2011-2022 走看看