《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

转载于:https://www.cnblogs.com/maying3010/p/6821406.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值