how tomcat works<三>

Catalina有两个主要的模块:connector和container,connector接收http请求,发送给container进行处理。container必须创建HttpServletRequest和HttpServletResponse的实例,然后传递给被调用的servlet的service方法。在这篇文章的应用中,connector解析HTTP请求头,并允许servlet获取headers, cookies, parameter names/values。

本篇的应用由三个模块组成:connector, startup, 和core.

startup模块仅包含一个类:BootStrap,它是应用的入口

connector模块分为5个类别:

  • connector 和它的支持(supporting )类(HttpConnector 和HttpProcessor )
  • 代表HTTP 请求的类(HttpRequest )及 其支持类
  • 代表HTTP 响应的类(HttpResponse )及其支持类
  • 门面(Facade )类(HttpRequestFacade 和HttpResponseFacade )
  • Constant 类
core模块包含两个类: ServletProcessor and StaticResourceProcessor


在这章的应用中,监听HTTP请求的任务交给了HttpConnector类,创建http请求和响应的任务交给了HttpProcessor类。HttpRequest类代表一个请求,HttpRespons代表一个响应。HttpRequest必须实现javax.servlet.http.HttpServletRequest接口。一个HttpRequest对象将会被转换成(cast)HttpServletRequest的实例然后传递给被请求的servlet的service方法。因此,每个HttpRequest的实例必须拥有合适的成员,被分配给HttpRequest的值有:URI, query string, parameters, cookies and 其他的 headers

SocketInputStream类包含两个重要的方法:readRequestLine和readHeader。readRequestLine返回请求字符串的第一行,readHeader用来获取名值对。


本篇的应用包含如下的结构:

 Starting the Application
 The Connector
 Creating an HttpRequest Object
 Creating an HttpResponse Object
 Static resource processor and servlet processor
 Running the Application


Starting the Application

ex03.pyrmont.startup.Bootstrap类为起点类,源代码如下:

[java]  view plain copy
  1. package ex03.pyrmont.startup;  
  2.   
  3. import ex03.pyrmont.connector.http.HttpConnector;  
  4.   
  5. public final class Bootstrap {  
  6.   public static void main(String[] args) {  
  7.     HttpConnector connector = new HttpConnector();  
  8.     connector.start();  
  9.   }  
  10. }  

[java]  view plain copy
  1. HttpConnector类的main方法实例化一个HttpConnector,然后调用它的start方法,启动一个线程  
[java]  view plain copy
  1.   
[java]  view plain copy
  1. <pre name="code" class="java">HttpConnector类的代码如下:</pre><pre name="code" class="java"><pre name="code" class="java">package ex03.pyrmont.connector.http;  
  2.   
  3. import java.io.IOException;  
  4. import java.net.InetAddress;  
  5. import java.net.ServerSocket;  
  6. import java.net.Socket;  
  7.   
  8. public class HttpConnector implements Runnable {  
  9.   
  10.   boolean stopped;  
  11.   private String scheme = "http";  
  12.   
  13.   public String getScheme() {  
  14.     return scheme;  
  15.   }  
  16.   
  17.   public void run() {  
  18.     ServerSocket serverSocket = null;  
  19.     int port = 8080;  
  20.     try {  
  21.       serverSocket =  new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));  
  22.     }  
  23.     catch (IOException e) {  
  24.       e.printStackTrace();  
  25.       System.exit(1);  
  26.     }  
  27.     while (!stopped) {  
  28.       // Accept the next incoming connection from the server socket  
  29.       Socket socket = null;  
  30.       try {  
  31.         socket = serverSocket.accept();  
  32.       }  
  33.       catch (Exception e) {  
  34.         continue;  
  35.       }  
  36.       // Hand this socket off to an HttpProcessor  
  37.       HttpProcessor processor = new HttpProcessor(this);  
  38.       processor.process(socket);  
  39.     }  
  40.   }  
  41.   
  42.   public void start() {  
  43.     Thread thread = new Thread(this);  
  44.     thread.start();  
  45.   }  
  46. }</pre><br>  
  47. 我们来看看HttpProcessor的processor方法:<p></p>  
  48. <pre></pre>  
  49. <pre name="code" class="java"><pre name="code" class="java"public void process(Socket socket) {  
  50.     SocketInputStream input = null;  
  51.     OutputStream output = null;  
  52.     try {  
  53.       input = new SocketInputStream(socket.getInputStream(), 2048);  
  54.       output = socket.getOutputStream();  
  55.   
  56.       // create HttpRequest object and parse  
  57.       request = new HttpRequest(input);  
  58.   
  59.       // create HttpResponse object  
  60.       response = new HttpResponse(output);  
  61.       response.setRequest(request);  
  62.   
  63.       response.setHeader("Server""Pyrmont Servlet Container");  
  64.   
  65.       parseRequest(input, output);  
  66.       parseHeaders(input);  
  67.   
  68.       //check if this is a request for a servlet or a static resource  
  69.       //a request for a servlet begins with "/servlet/"  
  70.       if (request.getRequestURI().startsWith("/servlet/")) {  
  71.         ServletProcessor processor = new ServletProcessor();  
  72.         processor.process(request, response);  
  73.       }  
  74.       else {  
  75.         StaticResourceProcessor processor = new StaticResourceProcessor();  
  76.         processor.process(request, response);  
  77.       }  
  78.   
  79.       // Close the socket  
  80.       socket.close();  
  81.       // no shutdown for this application  
  82.     }  
  83.     catch (Exception e) {  
  84.       e.printStackTrace();  
  85.     }  
  86.   }  
  87. </pre><br>  
  88. <span style="font-size:24px"><strong><br>  
  89. 创建HttpRequest对象 </strong></span>  
  90. <pre></pre>  
  91. <pre name="code" class="java"><span style="font-size:14px;">httpRequest类实现了javax.servlet.http.HttpServletRequest接口,类图如下:</span></pre><pre name="code" class="java"><img src="https://img-blog.csdn.net/20130903030707843?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VuamluZ3l1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">  
  92.   
  93. </pre><pre name="code" class="java">HttpRequest的代码如下:<pre name="code" class="java">package ex03.pyrmont.connector.http;  
  94.   
  95. /** this class copies methods from org.apache.catalina.connector.HttpRequestBase 
  96.  *  and org.apache.catalina.connector.http.HttpRequestImpl. 
  97.  *  The HttpRequestImpl class employs a pool of HttpHeader objects for performance 
  98.  *  These two classes will be explained in Chapter 4. 
  99.  */  
  100. import ex03.pyrmont.connector.RequestStream;  
  101. import javax.servlet.http.HttpServletRequest;  
  102. import javax.servlet.http.HttpSession;  
  103. import javax.servlet.http.Cookie;  
  104. import javax.servlet.RequestDispatcher;  
  105. import javax.servlet.ServletInputStream;  
  106. import java.security.Principal;  
  107. import java.io.InputStream;  
  108. import java.io.InputStreamReader;  
  109. import java.io.IOException;  
  110. import java.io.BufferedReader;  
  111. import java.io.UnsupportedEncodingException;  
  112. import java.net.InetAddress;  
  113. import java.net.Socket;  
  114. import java.text.ParseException;  
  115. import java.text.SimpleDateFormat;  
  116. import java.util.ArrayList;  
  117. import java.util.Date;  
  118. import java.util.Enumeration;  
  119. import java.util.HashMap;  
  120. import java.util.Locale;  
  121. import java.util.Map;  
  122. import org.apache.catalina.util.Enumerator;  
  123. import org.apache.catalina.util.ParameterMap;  
  124. import org.apache.catalina.util.RequestUtil;  
  125.   
  126. public class HttpRequest implements HttpServletRequest {  
  127.   
  128.   private String contentType;  
  129.   private int contentLength;  
  130.   private InetAddress inetAddress;  
  131.   private InputStream input;  
  132.   private String method;  
  133.   private String protocol;  
  134.   private String queryString;  
  135.   private String requestURI;  
  136.   private String serverName;  
  137.   private int serverPort;  
  138.   private Socket socket;  
  139.   private boolean requestedSessionCookie;  
  140.   private String requestedSessionId;  
  141.   private boolean requestedSessionURL;  
  142.   
  143.   /** 
  144.    * The request attributes for this request. 
  145.    */  
  146.   protected HashMap attributes = new HashMap();  
  147.   /** 
  148.    * The authorization credentials sent with this Request. 
  149.    */  
  150.   protected String authorization = null;  
  151.   /** 
  152.    * The context path for this request. 
  153.    */  
  154.   protected String contextPath = "";  
  155.   /** 
  156.    * The set of cookies associated with this Request. 
  157.    */  
  158.   protected ArrayList cookies = new ArrayList();  
  159.   /** 
  160.    * An empty collection to use for returning empty Enumerations.  Do not 
  161.    * add any elements to this collection! 
  162.    */  
  163.   protected static ArrayList empty = new ArrayList();  
  164.   /** 
  165.    * The set of SimpleDateFormat formats to use in getDateHeader(). 
  166.    */  
  167.   protected SimpleDateFormat formats[] = {  
  168.     new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),  
  169.     new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),  
  170.     new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)  
  171.   };  
  172.   
  173.   /** 
  174.    * The HTTP headers associated with this Request, keyed by name.  The 
  175.    * values are ArrayLists of the corresponding header values. 
  176.    */  
  177.   protected HashMap headers = new HashMap();  
  178.   /** 
  179.    * The parsed parameters for this request.  This is populated only if 
  180.    * parameter information is requested via one of the 
  181.    * <code>getParameter()</code> family of method calls.  The key is the 
  182.    * parameter name, while the value is a String array of values for this 
  183.    * parameter. 
  184.    * <p> 
  185.    * <strong>IMPLEMENTATION NOTE</strong> - Once the parameters for a 
  186.    * particular request are parsed and stored here, they are not modified. 
  187.    * Therefore, application level access to the parameters need not be 
  188.    * synchronized. 
  189.    */  
  190.   protected ParameterMap parameters = null;  
  191.   
  192.   /** 
  193.    * Have the parameters for this request been parsed yet? 
  194.    */  
  195.   protected boolean parsed = false;  
  196.   protected String pathInfo = null;  
  197.   
  198.   /** 
  199.    * The reader that has been returned by <code>getReader</code>, if any. 
  200.    */  
  201.   protected BufferedReader reader = null;  
  202.   
  203.   /** 
  204.    * The ServletInputStream that has been returned by 
  205.    * <code>getInputStream()</code>, if any. 
  206.    */  
  207.   protected ServletInputStream stream = null;  
  208.   
  209.   public HttpRequest(InputStream input) {  
  210.     this.input = input;  
  211.   }  
  212.   
  213.   public void addHeader(String name, String value) {  
  214.     name = name.toLowerCase();  
  215.     synchronized (headers) {  
  216.       ArrayList values = (ArrayList) headers.get(name);  
  217.       if (values == null) {  
  218.         values = new ArrayList();  
  219.         headers.put(name, values);  
  220.       }  
  221.       values.add(value);  
  222.     }  
  223.   }  
  224.   
  225.   /** 
  226.    * Parse the parameters of this request, if it has not already occurred. 
  227.    * If parameters are present in both the query string and the request 
  228.    * content, they are merged. 
  229.    */  
  230.   protected void parseParameters() {  
  231.     if (parsed)  
  232.       return;  
  233.     ParameterMap results = parameters;  
  234.     if (results == null)  
  235.       results = new ParameterMap();  
  236.     results.setLocked(false);  
  237.     String encoding = getCharacterEncoding();  
  238.     if (encoding == null)  
  239.       encoding = "ISO-8859-1";  
  240.   
  241.     // Parse any parameters specified in the query string  
  242.     String queryString = getQueryString();  
  243.     try {  
  244.       RequestUtil.parseParameters(results, queryString, encoding);  
  245.     }  
  246.     catch (UnsupportedEncodingException e) {  
  247.       ;  
  248.     }  
  249.   
  250.     // Parse any parameters specified in the input stream  
  251.     String contentType = getContentType();  
  252.     if (contentType == null)  
  253.       contentType = "";  
  254.     int semicolon = contentType.indexOf(';');  
  255.     if (semicolon >= 0) {  
  256.       contentType = contentType.substring(0, semicolon).trim();  
  257.     }  
  258.     else {  
  259.       contentType = contentType.trim();  
  260.     }  
  261.     if ("POST".equals(getMethod()) && (getContentLength() > 0)  
  262.       && "application/x-www-form-urlencoded".equals(contentType)) {  
  263.       try {  
  264.         int max = getContentLength();  
  265.         int len = 0;  
  266.         byte buf[] = new byte[getContentLength()];  
  267.         ServletInputStream is = getInputStream();  
  268.         while (len < max) {  
  269.           int next = is.read(buf, len, max - len);  
  270.           if (next < 0 ) {  
  271.             break;  
  272.           }  
  273.           len += next;  
  274.         }  
  275.         is.close();  
  276.         if (len < max) {  
  277.           throw new RuntimeException("Content length mismatch");  
  278.         }  
  279.         RequestUtil.parseParameters(results, buf, encoding);  
  280.       }  
  281.       catch (UnsupportedEncodingException ue) {  
  282.         ;  
  283.       }  
  284.       catch (IOException e) {  
  285.         throw new RuntimeException("Content read fail");  
  286.       }  
  287.     }  
  288.   
  289.     // Store the final results  
  290.     results.setLocked(true);  
  291.     parsed = true;  
  292.     parameters = results;  
  293.   }  
  294.   
  295.   public void addCookie(Cookie cookie) {  
  296.     synchronized (cookies) {  
  297.       cookies.add(cookie);  
  298.     }  
  299.   }  
  300.   
  301.   /** 
  302.    * Create and return a ServletInputStream to read the content 
  303.    * associated with this Request.  The default implementation creates an 
  304.    * instance of RequestStream associated with this request, but this can 
  305.    * be overridden if necessary. 
  306.    * 
  307.    * @exception IOException if an input/output error occurs 
  308.    */  
  309.   public ServletInputStream createInputStream() throws IOException {  
  310.     return (new RequestStream(this));  
  311.   }  
  312.   
  313.   public InputStream getStream() {  
  314.     return input;  
  315.   }  
  316.   public void setContentLength(int length) {  
  317.     this.contentLength = length;  
  318.   }  
  319.   
  320.   public void setContentType(String type) {  
  321.     this.contentType = type;  
  322.   }  
  323.   
  324.   public void setInet(InetAddress inetAddress) {  
  325.     this.inetAddress = inetAddress;  
  326.   }  
  327.   
  328.   public void setContextPath(String path) {  
  329.     if (path == null)  
  330.       this.contextPath = "";  
  331.     else  
  332.       this.contextPath = path;  
  333.   }  
  334.   
  335.   public void setMethod(String method) {  
  336.     this.method = method;  
  337.   }  
  338.   
  339.   public void setPathInfo(String path) {  
  340.     this.pathInfo = path;  
  341.   }  
  342.   
  343.   public void setProtocol(String protocol) {  
  344.     this.protocol = protocol;  
  345.   }  
  346.   
  347.   public void setQueryString(String queryString) {  
  348.     this.queryString = queryString;  
  349.   }  
  350.   
  351.   public void setRequestURI(String requestURI) {  
  352.     this.requestURI = requestURI;  
  353.   }  
  354.   /** 
  355.    * Set the name of the server (virtual host) to process this request. 
  356.    * 
  357.    * @param name The server name 
  358.    */  
  359.   public void setServerName(String name) {  
  360.     this.serverName = name;  
  361.   }  
  362.   /** 
  363.    * Set the port number of the server to process this request. 
  364.    * 
  365.    * @param port The server port 
  366.    */  
  367.   public void setServerPort(int port) {  
  368.     this.serverPort = port;  
  369.   }  
  370.   
  371.   public void setSocket(Socket socket) {  
  372.     this.socket = socket;  
  373.   }  
  374.   
  375.   /** 
  376.    * Set a flag indicating whether or not the requested session ID for this 
  377.    * request came in through a cookie.  This is normally called by the 
  378.    * HTTP Connector, when it parses the request headers. 
  379.    * 
  380.    * @param flag The new flag 
  381.    */  
  382.   public void setRequestedSessionCookie(boolean flag) {  
  383.     this.requestedSessionCookie = flag;  
  384.   }  
  385.   
  386.   public void setRequestedSessionId(String requestedSessionId) {  
  387.     this.requestedSessionId = requestedSessionId;  
  388.   }  
  389.   
  390.   public void setRequestedSessionURL(boolean flag) {  
  391.     requestedSessionURL = flag;  
  392.   }  
  393.   
  394.   /* implementation of the HttpServletRequest*/  
  395.   public Object getAttribute(String name) {  
  396.     synchronized (attributes) {  
  397.       return (attributes.get(name));  
  398.     }  
  399.   }  
  400.   
  401.   public Enumeration getAttributeNames() {  
  402.     synchronized (attributes) {  
  403.       return (new Enumerator(attributes.keySet()));  
  404.     }  
  405.   }  
  406.   
  407.   public String getAuthType() {  
  408.     return null;  
  409.   }  
  410.   
  411.   public String getCharacterEncoding() {  
  412.     return null;  
  413.   }  
  414.   
  415.   public int getContentLength() {  
  416.     return contentLength ;  
  417.   }  
  418.   
  419.   public String getContentType() {  
  420.     return contentType;  
  421.   }  
  422.   
  423.   public String getContextPath() {  
  424.     return contextPath;  
  425.   }  
  426.   
  427.   public Cookie[] getCookies() {  
  428.     synchronized (cookies) {  
  429.       if (cookies.size() < 1)  
  430.         return (null);  
  431.       Cookie results[] = new Cookie[cookies.size()];  
  432.       return ((Cookie[]) cookies.toArray(results));  
  433.     }  
  434.   }  
  435.   
  436.   public long getDateHeader(String name) {  
  437.     String value = getHeader(name);  
  438.     if (value == null)  
  439.       return (-1L);  
  440.   
  441.     // Work around a bug in SimpleDateFormat in pre-JDK1.2b4  
  442.     // (Bug Parade bug #4106807)  
  443.     value += " ";  
  444.   
  445.     // Attempt to convert the date header in a variety of formats  
  446.     for (int i = 0; i < formats.length; i++) {  
  447.       try {  
  448.         Date date = formats[i].parse(value);  
  449.         return (date.getTime());  
  450.       }  
  451.       catch (ParseException e) {  
  452.         ;  
  453.       }  
  454.     }  
  455.     throw new IllegalArgumentException(value);  
  456.   }  
  457.   
  458.   public String getHeader(String name) {  
  459.     name = name.toLowerCase();  
  460.     synchronized (headers) {  
  461.       ArrayList values = (ArrayList) headers.get(name);  
  462.       if (values != null)  
  463.         return ((String) values.get(0));  
  464.       else  
  465.         return null;  
  466.     }  
  467.   }  
  468.   
  469.   public Enumeration getHeaderNames() {  
  470.     synchronized (headers) {  
  471.       return (new Enumerator(headers.keySet()));  
  472.     }  
  473.   }  
  474.   
  475.   public Enumeration getHeaders(String name) {  
  476.     name = name.toLowerCase();  
  477.     synchronized (headers) {  
  478.       ArrayList values = (ArrayList) headers.get(name);  
  479.       if (values != null)  
  480.         return (new Enumerator(values));  
  481.       else  
  482.         return (new Enumerator(empty));  
  483.     }  
  484.   }  
  485.   
  486.   public ServletInputStream getInputStream() throws IOException {  
  487.     if (reader != null)  
  488.       throw new IllegalStateException("getInputStream has been called");  
  489.   
  490.     if (stream == null)  
  491.       stream = createInputStream();  
  492.     return (stream);  
  493.   }  
  494.   
  495.   public int getIntHeader(String name) {  
  496.     String value = getHeader(name);  
  497.     if (value == null)  
  498.       return (-1);  
  499.     else  
  500.       return (Integer.parseInt(value));  
  501.   }  
  502.   
  503.   public Locale getLocale() {  
  504.     return null;  
  505.   }  
  506.   
  507.   public Enumeration getLocales() {  
  508.     return null;  
  509.   }  
  510.   
  511.   public String getMethod() {  
  512.     return method;  
  513.   }  
  514.   
  515.   public String getParameter(String name) {  
  516.     parseParameters();  
  517.     String values[] = (String[]) parameters.get(name);  
  518.     if (values != null)  
  519.       return (values[0]);  
  520.     else  
  521.       return (null);  
  522.   }  
  523.   
  524.   public Map getParameterMap() {  
  525.     parseParameters();  
  526.     return (this.parameters);  
  527.   }  
  528.   
  529.   public Enumeration getParameterNames() {  
  530.     parseParameters();  
  531.     return (new Enumerator(parameters.keySet()));  
  532.   }  
  533.   
  534.   public String[] getParameterValues(String name) {  
  535.     parseParameters();  
  536.     String values[] = (String[]) parameters.get(name);  
  537.     if (values != null)  
  538.       return (values);  
  539.     else  
  540.       return null;  
  541.   }  
  542.   
  543.   public String getPathInfo() {  
  544.     return pathInfo;  
  545.   }  
  546.   
  547.   public String getPathTranslated() {  
  548.     return null;  
  549.   }  
  550.   
  551.   public String getProtocol() {  
  552.     return protocol;  
  553.   }  
  554.   
  555.   public String getQueryString() {  
  556.     return queryString;  
  557.   }  
  558.   
  559.   public BufferedReader getReader() throws IOException {  
  560.     if (stream != null)  
  561.       throw new IllegalStateException("getInputStream has been called.");  
  562.     if (reader == null) {  
  563.       String encoding = getCharacterEncoding();  
  564.       if (encoding == null)  
  565.         encoding = "ISO-8859-1";  
  566.       InputStreamReader isr =  
  567.         new InputStreamReader(createInputStream(), encoding);  
  568.         reader = new BufferedReader(isr);  
  569.     }  
  570.     return (reader);  
  571.   }  
  572.   
  573.   public String getRealPath(String path) {  
  574.     return null;  
  575.   }  
  576.   
  577.   public String getRemoteAddr() {  
  578.     return null;  
  579.   }  
  580.   
  581.   public String getRemoteHost() {  
  582.     return null;  
  583.   }  
  584.   
  585.   public String getRemoteUser() {  
  586.     return null;  
  587.   }  
  588.   
  589.   public RequestDispatcher getRequestDispatcher(String path) {  
  590.     return null;  
  591.   }  
  592.   
  593.   public String getScheme() {  
  594.    return null;  
  595.   }  
  596.   
  597.   public String getServerName() {  
  598.     return null;  
  599.   }  
  600.   
  601.   public int getServerPort() {  
  602.     return 0;  
  603.   }  
  604.   
  605.   public String getRequestedSessionId() {  
  606.     return null;  
  607.   }  
  608.   
  609.   public String getRequestURI() {  
  610.     return requestURI;  
  611.   }  
  612.   
  613.   public StringBuffer getRequestURL() {  
  614.     return null;  
  615.   }  
  616.   
  617.   public HttpSession getSession() {  
  618.     return null;  
  619.   }  
  620.   
  621.   public HttpSession getSession(boolean create) {  
  622.     return null;  
  623.   }  
  624.   
  625.   public String getServletPath() {  
  626.     return null;  
  627.   }  
  628.   
  629.   public Principal getUserPrincipal() {  
  630.     return null;  
  631.   }  
  632.   
  633.   public boolean isRequestedSessionIdFromCookie() {  
  634.     return false;  
  635.   }  
  636.   
  637.   public boolean isRequestedSessionIdFromUrl() {  
  638.     return isRequestedSessionIdFromURL();  
  639.   }  
  640.   
  641.   public boolean isRequestedSessionIdFromURL() {  
  642.     return false;  
  643.   }  
  644.   
  645.   public boolean isRequestedSessionIdValid() {  
  646.     return false;  
  647.   }  
  648.   
  649.   public boolean isSecure() {  
  650.     return false;  
  651.   }  
  652.   
  653.   public boolean isUserInRole(String role) {  
  654.     return false;  
  655.   }  
  656.   
  657.   public void removeAttribute(String attribute) {  
  658.   }  
  659.   
  660.   public void setAttribute(String key, Object value) {  
  661.   }  
  662.   
  663.   /** 
  664.    * Set the authorization credentials sent with this request. 
  665.    * 
  666.    * @param authorization The new authorization credentials 
  667.    */  
  668.   public void setAuthorization(String authorization) {  
  669.     this.authorization = authorization;  
  670.   }  
  671.   
  672.   public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException {  
  673.   }  
  674.   
  675. public String getLocalAddr() {  
  676.     // TODO Auto-generated method stub  
  677.     return null;  
  678. }  
  679.   
  680. public String getLocalName() {  
  681.     // TODO Auto-generated method stub  
  682.     return null;  
  683. }  
  684.   
  685. public int getLocalPort() {  
  686.     // TODO Auto-generated method stub  
  687.     return 0;  
  688. }  
  689.   
  690. public int getRemotePort() {  
  691.     // TODO Auto-generated method stub  
  692.     return 0;  
  693. }  
  694. }  
  695. </pre><br>  
  696. <pre></pre>  
  697. <pre name="code" class="java">HttpRequest类包含如下子内容:</pre><pre name="code" class="java"><ul style="margin: 0px 0px 1.5em; padding: 0px;"><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">读取套接字的输入流</li><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">解析请求行</li><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">解析headers</li><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">解析cookies</li><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">获取请求参数</li></ul></pre>  
  698. <pre></pre>  
  699. <pre name="code" class="java"></pre><br>  
  700. <p></p>  
  701. <p><br>  
  702. </p>  

  1. </pre></pre></pre>  

转自:http://blog.csdn.net/wenjingyu/article/details/10952597

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值