程序模拟tomcat服务器执行过程
2011-12-12 17:03
211 查看
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,不论你文件在哪里,你要访问它你都需要给它提供路径的,没有路径它不会自动的去寻找的。就算是它会自动寻找
当出现了两个文件名一样的文件的时候,在不同的目录下,你说让它返回谁?
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,不论你文件在哪里,你要访问它你都需要给它提供路径的,没有路径它不会自动的去寻找的。就算是它会自动寻找
当出现了两个文件名一样的文件的时候,在不同的目录下,你说让它返回谁?
相关文章推荐
- Linux下安装MyEclipse和Tomcat服务器详解,以及我安装过程中所出现的问题以及解决办法,并实现一个web小程序
- java程序模拟浏览器访问Web服务器的处理过程
- C#程序调用Delphi可执行EXE文件过程
- Hadoop入门程序WordCount的执行过程
- linux下C程序从编写到执行完整过程
- 程序执行过程
- 部署MyEclipse工具中的Web程序到TomCat服务器并启动Web程序
- java/c程序执行过程
- 源代码生成可执行程序过程
- 程序的编译与执行过程
- Tomcat服务器的模拟实现学习解析Http协议、反射、xml解析等
- 第9周 程序阅读-6 (单步执行过程)
- 面向对象第三课,程序执行过程的内存分析,堆、栈分析
- 程序的实现过程(编译、链接、执行)
- wxWidgets程序整体框架及其执行过程
- java程序执行过程及静态块、非静态块执行顺序
- 我的servlet学习过程(二):tomcat服务器部分
- 一个程序的执行过程
- iphone程序的生命周期(执行过程)
- 在SQL SERVER中执行链接服务器上的带有参数的存储过程