• 《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
  • 相关阅读:
    课表
    hz评测机的迷惑操作
    联赛模拟测试16
    第四阶段总结
    震惊!OI居然还考天体运动
    简单题 题解
    P2340 [USACO03FALL]Cow Exhibition G题解
    题目分享I 三代目
    题目分享H 三代目
    题目分享G 三代目
  • 原文地址:https://www.cnblogs.com/maying3010/p/6821406.html
Copyright © 2020-2023  润新知