怎么做网站seo优化,wordpress升级后出错,网站描本链接怎么做,东莞做小程序的公司这里要介绍下Tomcat的一个重要设计方法#xff0c;Catalina设计方式。 Servlet容器是一个复杂系统#xff0c;但是#xff0c;它有三个基本任务#xff0c;对每个请求#xff0c;servlet容器会为其完成以下三个操作#xff1a; 1.创建一个Request对象#xff0c;用可能会… 这里要介绍下Tomcat的一个重要设计方法Catalina设计方式。 Servlet容器是一个复杂系统但是它有三个基本任务对每个请求servlet容器会为其完成以下三个操作 1.创建一个Request对象用可能会在调用的Servlet中使用到的信息填充该request对象如参数、头、cookie、查询字符串、URI等。 request对象是javax.servlet.ServletRequest接口或javax.servlet.http.ServletRequest接口的一个实例。 2.创建一个调用Servlet的response对象用来向Web客户端发送响应。response对象是javax.servlet.ServletResponse接口或javax.servlet.http.ServletResponse接口的一个实例。 3.调用Servlet的service()方法将request对象和response对象作为参数传入。Servlet从request对象中读取信息并通过response对象发送响应信息。 ----------------------------------------------------------------------------------------------------- Catalina是一个成熟的软件设计和开发得十分优雅。其实我在公司项目中发现的使用方法也是这样的十分的优雅的软件开发方式 Catalina使得软件开发功能结构编程模块化的基于上文提到的servlet容器的任务可以将Catalina划分为两个模块连接器connector和容器container 连接器负责将一个请求与容器相关联。它的工作包括为它接收到的每一个HTTP请求创建一个Request对象和一个Response对象。然后它将处理过程交给容器。容器从连接器中接收到Request对象和Response对象并负责调用相应的Servlet的service()方法。 简而言这模式就是connector负责接收请求创建解析请求需要的Request对象和Response对象然后将请求分发到容器中处理。 普通的服务端结构一般也是这么设计的IO部分负责接收请求创建解析请求的对象然后将请求丢进线程池中进行处理 xxxx -------------------------------------------- 现在根据模块开发Servlet容器 1连接器 HttpConnector和HttpProcessor 连接器及其支持类 标示HTTP请求的类HTTPRequest及其支持类 负责HTTP响应的类HttpResponse以及其支持类外观类以及常量类 2启动模块 启动模块包括一个类就是startup.Bootstrap 类负责启动应用程序。 3核心模块 启动类 package ex03.pyrmont.startup;import ex03.pyrmont.connector.http.HttpConnector;public final class Bootstrap
{public static void main(String[] args){HttpConnector connector new HttpConnector();connector.start();}
}关于这个建议具有连接器和容器功能的Http服务器 http://www.cnblogs.com/wuxinliulei/p/4967625.html 重点介绍这个模型当中对HTTP请求信息的parse HttpConnector类在接收到连接请求后将请求派发给一个HttpProcessor对象处理 import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;public class HttpConnector implements Runnable
{boolean stopped;private String scheme http;public String getScheme(){return scheme;}public void run(){ServerSocket serverSocket null;int port 8080;try{serverSocket new ServerSocket(port, 1, InetAddress.getByName(127.0.0.1));} catch (IOException e){e.printStackTrace();System.exit(1);}while (!stopped){// Accept the next incoming connection from the server socketSocket socket null;try{socket serverSocket.accept();} catch (Exception e){continue;}// Hand this socket off to an HttpProcessorHttpProcessor processor new HttpProcessor(this);processor.process(socket);}}public void start(){Thread thread new Thread(this);thread.start();}
}将此次连接获取的Socket对象传入调用HttpProcessor对象的process方法来处理Http请求 下面是HttpProcessor对象的process方法重点关注SocketInputStream对象SocketInputStream对象是对InputStream对象的一层包装封装了一些对Http请求解析方便的方法。 public void process(Socket socket){SocketInputStream input null;OutputStream output null;try{input new SocketInputStream(socket.getInputStream(), 2048);output socket.getOutputStream();// create HttpRequest object and parserequest new HttpRequest(input);// create HttpResponse objectresponse new HttpResponse(output);response.setRequest(request);response.setHeader(Server, Pyrmont Servlet Container);parseRequest(input, output);parseHeaders(input);// check if this is a request for a servlet or a static resource// a request for a servlet begins with /servlet/if (request.getRequestURI().startsWith(/servlet/)){ServletProcessor processor new ServletProcessor();processor.process(request, response);} else{StaticResourceProcessor processor new StaticResourceProcessor();processor.process(request, response);}// Close the socketsocket.close();// no shutdown for this application} catch (Exception e){e.printStackTrace();}}process方法当中调用了parseRequest方法该方法传入SocketInputStream对象和OutputStream对象方法对输入流当中的http请求进行了解析 这里牵涉到几个帮助类 1HttpRequestLine类定义在HttpProcessor方法的成员变量当中。private HttpRequestLine requestLine new HttpRequestLine(); 该类中对http请求内容中的请求行http请求依次分为请求行、请求头、/r/n,请求体四部分第一行内容进行了解析 即 POST /servlet/primitServlet Http/1.1 GET /sample/hello.jsp HTTP/1.1 这样的内容 HttpRequestLine类是一个可以复用的类PS但是HttpProcessor在这个框架当中没有对象池的复用所以没有卵用对httpMethod httpUrl protocol 三部分做了处理。其中还提供了字符串匹配的方法indexOf(char[] xxx) indexOf(String xxx) /*** HTTP request line enum type.*/final class HttpRequestLine
{// -------------------------------------------------------------- Constantspublic static final int INITIAL_METHOD_SIZE 8;public static final int INITIAL_URI_SIZE 64;public static final int INITIAL_PROTOCOL_SIZE 8;public static final int MAX_METHOD_SIZE 1024;public static final int MAX_URI_SIZE 32768;public static final int MAX_PROTOCOL_SIZE 1024;// ----------------------------------------------------------- Constructorspublic HttpRequestLine(){this(new char[INITIAL_METHOD_SIZE], 0, new char[INITIAL_URI_SIZE], 0, new char[INITIAL_PROTOCOL_SIZE], 0);}public HttpRequestLine(char[] method, int methodEnd, char[] uri, int uriEnd, char[] protocol, int protocolEnd){this.method method;this.methodEnd methodEnd;this.uri uri;this.uriEnd uriEnd;this.protocol protocol;this.protocolEnd protocolEnd;}// ----------------------------------------------------- Instance Variablespublic char[] method;public int methodEnd;public char[] uri;public int uriEnd;public char[] protocol;public int protocolEnd;// ------------------------------------------------------------- Properties// --------------------------------------------------------- Public Methods/*** Release all object references, and initialize instance variables, in* preparation for reuse of this object.*/public void recycle(){methodEnd 0;uriEnd 0;protocolEnd 0;}/*** Test if the uri includes the given char array.*/public int indexOf(char[] buf){return indexOf(buf, buf.length);}/*** Test if the value of the header includes the given char array.*/public int indexOf(char[] buf, int end){char firstChar buf[0];int pos 0;while (pos uriEnd){pos indexOf(firstChar, pos);if (pos -1)return -1;if ((uriEnd - pos) end)return -1;for (int i 0; i end; i){if (uri[i pos] ! buf[i])break;if (i (end - 1))return pos;}pos;}return -1;}/*** Test if the value of the header includes the given string.*/public int indexOf(String str){return indexOf(str.toCharArray(), str.length());}/*** Returns the index of a character in the value.*/public int indexOf(char c, int start){for (int i start; i uriEnd; i){if (uri[i] c)return i;}return -1;}// --------------------------------------------------------- Object Methodspublic int hashCode(){// FIXMEreturn 0;}public boolean equals(Object obj){return false;}}我们要注意到parseRequest方法的第一行代码 input.readRequestLinerequestLine SocketInputStream的该方法完成了对HttpRequestLine对象的初始化主要初始化了六个对象 public char[] method; //method对象 public int methodEnd; //method对象的结束位置 public char[] uri; //uri对象 public int uriEnd; //uri对象的结束位置 public char[] protocol; //协议对象 public int protocolEnd;//协议对象的结束位置 注意read方法完成了对count的初始化并且将第一行内容缓存到char[] buf当中 /*** Read byte.*/public int read() throws IOException{if (pos count){fill();if (pos count)return -1;}return buf[pos] 0xff;}/*** Fill the internal buffer using data from the undelying input stream.*/protected void fill() throws IOException{pos 0;count 0;int nRead is.read(buf, 0, buf.length);if (nRead 0){count nRead;}}public void readRequestLine(HttpRequestLine requestLine) throws IOException{// Recycling checkif (requestLine.methodEnd ! 0)requestLine.recycle();// Checking for a blank lineint chr 0;do{ // Skipping CR or LFtry{chr read();} catch (IOException e){chr -1;}} while ((chr CR) || (chr LF));if (chr -1)throw new EOFException(sm.getString(requestStream.readline.error));pos--;// Reading the method nameint maxRead requestLine.method.length;int readStart pos;int readCount 0;boolean space false;while (!space){// if the buffer is full, extend itif (readCount maxRead){if ((2 * maxRead) HttpRequestLine.MAX_METHOD_SIZE){char[] newBuffer new char[2 * maxRead];System.arraycopy(requestLine.method, 0, newBuffer, 0, maxRead);requestLine.method newBuffer;maxRead requestLine.method.length;} else{throw new IOException(sm.getString(requestStream.readline.toolong));}}// Were at the end of the internal bufferif (pos count){int val read();if (val -1){throw new IOException(sm.getString(requestStream.readline.error));}pos 0;readStart 0;}if (buf[pos] SP){space true;}requestLine.method[readCount] (char) buf[pos];readCount;pos;}requestLine.methodEnd readCount - 1;// Reading URImaxRead requestLine.uri.length;readStart pos;readCount 0;space false;boolean eol false;while (!space){// if the buffer is full, extend itif (readCount maxRead){if ((2 * maxRead) HttpRequestLine.MAX_URI_SIZE){char[] newBuffer new char[2 * maxRead];System.arraycopy(requestLine.uri, 0, newBuffer, 0, maxRead);requestLine.uri newBuffer;maxRead requestLine.uri.length;} else{throw new IOException(sm.getString(requestStream.readline.toolong));}}// Were at the end of the internal bufferif (pos count){int val read();if (val -1)throw new IOException(sm.getString(requestStream.readline.error));pos 0;readStart 0;}if (buf[pos] SP){space true;} else if ((buf[pos] CR) || (buf[pos] LF)){// HTTP/0.9 style requesteol true;space true;}requestLine.uri[readCount] (char) buf[pos];readCount;pos;}//请求航URL结束requestLine.uriEnd readCount - 1;// Reading protocolmaxRead requestLine.protocol.length;readStart pos;readCount 0;while (!eol){// if the buffer is full, extend itif (readCount maxRead){if ((2 * maxRead) HttpRequestLine.MAX_PROTOCOL_SIZE){char[] newBuffer new char[2 * maxRead];System.arraycopy(requestLine.protocol, 0, newBuffer, 0, maxRead);requestLine.protocol newBuffer;maxRead requestLine.protocol.length;} else{throw new IOException(sm.getString(requestStream.readline.toolong));}}// Were at the end of the internal bufferif (pos count){// Copying part (or all) of the internal buffer to the line// bufferint val read();if (val -1)throw new IOException(sm.getString(requestStream.readline.error));pos 0;readStart 0;}if (buf[pos] CR){// Skip CR.} else if (buf[pos] LF){eol true;} else{requestLine.protocol[readCount] (char) buf[pos];readCount;}pos;}// HTTP/1.1requestLine.protocolEnd readCount;}private void parseRequest(SocketInputStream input, OutputStream output) throws IOException, ServletException{// Parse the incoming request lineinput.readRequestLine(requestLine);String method new String(requestLine.method, 0, requestLine.methodEnd);String uri null;String protocol new String(requestLine.protocol, 0, requestLine.protocolEnd);// Validate the incoming request lineif (method.length() 1){throw new ServletException(Missing HTTP request method);} else if (requestLine.uriEnd 1){throw new ServletException(Missing HTTP request URI);}// Parse any query parameters out of the request URIint question requestLine.indexOf(?);if (question 0){request.setQueryString(new String(requestLine.uri, question 1, requestLine.uriEnd - question - 1));uri new String(requestLine.uri, 0, question);} else{request.setQueryString(null);uri new String(requestLine.uri, 0, requestLine.uriEnd);}// Checking for an absolute URI (with the HTTP protocol)if (!uri.startsWith(/)){int pos uri.indexOf(://);// Parsing out protocol and host nameif (pos ! -1){pos uri.indexOf(/, pos 3);if (pos -1){uri ;} else{uri uri.substring(pos);}}}// Parse any requested session ID out of the request URIString match ;jsessionid;int semicolon uri.indexOf(match);if (semicolon 0){String rest uri.substring(semicolon match.length());int semicolon2 rest.indexOf(;);if (semicolon2 0){request.setRequestedSessionId(rest.substring(0, semicolon2));rest rest.substring(semicolon2);} else{request.setRequestedSessionId(rest);rest ;}request.setRequestedSessionURL(true);uri uri.substring(0, semicolon) rest;} else{request.setRequestedSessionId(null);request.setRequestedSessionURL(false);}// Normalize URI (using String operations at the moment)String normalizedUri normalize(uri);// Set the corresponding request properties((HttpRequest) request).setMethod(method);request.setProtocol(protocol);if (normalizedUri ! null){((HttpRequest) request).setRequestURI(normalizedUri);} else{((HttpRequest) request).setRequestURI(uri);}if (normalizedUri null){throw new ServletException(Invalid URI: uri );}}---------------------------------------------------------------------------------------------------------------------------------------- 为什么采用连接器的第三章的代码没有采用第二章的简单形式直接将相关内容解析出来呢 private String parseUri(String requestString){int index1, index2;index1 requestString.indexOf( );if (index1 ! -1){index2 requestString.indexOf( , index1 1);if (index2 index1)return requestString.substring(index1 1, index2);}return null;}public void parse()
{// Read a set of characters from the socketStringBuffer request new StringBuffer(2048);int i;byte[] buffer new byte[2048];try{i input.read(buffer);} catch (IOException e){e.printStackTrace();i -1;}for (int j 0; j i; j){request.append((char) buffer[j]);}System.out.print(request.toString());uri parseUri(request.toString());
}其实上面的处理方式是不严谨的应该读到/r/n之后停止而不是固定读取2048字节然后处理这读出来的字节。 转载于:https://www.cnblogs.com/wuxinliulei/p/4960670.html