您的位置:首页 > 运维架构 > Tomcat

程序模拟tomcat服务器执行过程

2011-12-12 17:03 369 查看
WebServer.java类

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

public class WebServer {

/**服务器默认使用的端口号**/

public static final int HTTP_PORT=8080;

//定义服务器的socket

private ServerSocket serverSocket;

/**

* WebServer类的启动方法,可以通过命令行参数指定当前的Web服务器所使用的端口号

*/

public static void main(String[] args) {

WebServer webServer=new WebServer();

if(args.length==1){

//使用指定的端口号

webServer.startServer(Integer.parseInt(args[0]));

} else {

//使用默认的端口号

webServer.startServer(HTTP_PORT);

}

}

public void startServer(int port) {

try {

//实例化ServerSocket

serverSocket=new ServerSocket(port);

System.out.println("server start at..."+port);

while(true) {

Socket socket=serverSocket.accept();

//通过线程的方式来处理客户的请求

new Processor(socket).start();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

Processor类

import java.io.BufferedReader;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.PrintStream;

import java.net.Socket;

/**

* 处理一个HTTP用户请求的线程类

*/

public class Processor extends Thread {

/**默认的服务器存放访问内容的目录**/

private static final String WEB_ROOT="C:\\Users\\Administrator\\Workspaces\\MyEclipse 8.5\\webserver_1\\htdocs";

//定义打印流

private PrintStream out;

//定义输入流

private InputStream in;

/**默认的构造方法**/

public Processor(Socket socket) {

try {

this.in=socket.getInputStream();

} catch (IOException e) {

e.printStackTrace();

}

try {

this.out=new PrintStream(socket.getOutputStream());

} catch (IOException e) {

e.printStackTrace();

}

}

@Override

public void run() {

try {

//获取文件名

String fileName=getFile(in);

//读取文件

readFile(fileName);

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 解析客户端发送过来的所有HTTP请求,如果是符合协议内容的,就分析出客户机要访问的文件的名字,并且返回文件名

*/

public String getFile(InputStream in) throws IOException {

BufferedReader br = new BufferedReader(new InputStreamReader(in));

String content=br.readLine();

if(content.length()==0) {

sendError(400, "Client invoke error");

return null;

}

//分析客户端发送过来的参数

//发送过来的请求包括三部分

String[] request=content.split(" ");

if(request.length!=3) {

sendError(400, "Client invoke error");

return null;

}

//第一部分是state code

String stateCode=request[0];

//第二部分是请求的文件

String fileName=request[1];

//第三部分是版本信息

String httpVersion=request[2];

System.out.println("state code: "+stateCode+"\tfileName: "+fileName+"\thttpVersion: "+httpVersion);

return fileName;

}

/**

* 处理调用一个文件的请求

*/

public void readFile(String fileName) throws IOException {

File f=new File(WEB_ROOT+fileName);

if(!f.exists()) {

sendError(400, "Client invoke error");

return;

}

FileInputStream in=new FileInputStream(f);

byte[] b=new byte[(int) f.length()];

in.read(b);

out.println("HTTP/1.0 200 sendFile");

out.println("Content-length: " + b.length);

out.println();

out.write(b);

out.flush();

out.close();

in.close();

}

public void sendError(int errNum,String errMsg) {

out.println("HTTP/1.0 " + errNum + " " + errMsg);

out.println("Content-type: text/html");

out.println();

out.println("<html>");

out.println("<head><title>Error " + errNum + "--" + errMsg + "</title></head>");

out.println("<h1>" + errNum + " " + errMsg + "</h1>");

out.println("</html>");

out.println();

out.flush();

out.close();

}

}

web请求的执行过程:客户端发送请求->请求以流的方式发送到服务器->服务器接受流->读取流内容->把内容存储在String中

->把String按照规则分开为三部分->获取第二部分(客户请求的文件名)->查找资源->把资源以流的读取出来存入数组->使用

printStream把流给write()给客户端;

tomcat执行步骤:通过url-pattern->servlet-name->servlet-class->编译->返回jsp文件

路径的配置:

1.访问action的时候路径的配置

action的路径配置,action的配置原理是这样的,客户端在地址栏输入了一个访问的servlet,这个时候客户点击

回车浏览器就会把你所输入的路径给发送到了服务器了,这个时候当tomcat接受到了请求之后它就会对请求进行处理,它会先分

离出你要访问的哪个文件,之后去web.xml里面去查找对应的servlet之后根据影射关系找到文件所在的地方,然后执行对应的servlet

里面的方法。

例如:/webproject2_1/login/loginServlet

这里面"/"代表的是当前工程所在的根根目录,而webproject2_1就是当前网站所在工程,然后后面的就是我要请求的文件了,这个时候

因为我请求的是servlet,所以这个时候tomcat会自动的去web.xml中去寻找对应<url-pattern>为/login/loginServlet的servlet对应的

servlet的servlet-name,之后根据servlet-name再去找这个名称对应的servlet所在的位置去调用这个servlet里面的方法执行,默认的

是get方法

2.访问jsp和html时的路径配置

如果是访问的jsp页面这个时候因为在web.xml中并没有对于jsp页面位置的配置,但是因为你要访问的任何的东西都会告诉浏览器

你要访问的资源的名字,比如html它是页面,很显然,tomcat也还是会去web.xml中去找,看看有没有相关的配置,如果没有就直接去tomcat

的根目录里面去寻找,总之如果有了web.xml,tomcat总是先去匹配是不是存在这样的servlet然后再去寻找是不是直接的存在这样的文件

如果找到了,就把页面返回给你,如果找不到对不起就返回错误了也许你会说我访问的文件不是直接的在web-root下的,而是在web-root下的test

文件夹下的a.html,不论你文件在哪里,你要访问它你都需要给它提供路径的,没有路径它不会自动的去寻找的。就算是它会自动寻找

当出现了两个文件名一样的文件的时候,在不同的目录下,你说让它返回谁?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: