自己动手编写tomcat服务器(一)
2013-08-22 05:38
351 查看
这篇博文来自于《how tomcat works》一书的第一章
我们的服务器程序由下列三个类组成:
HttpServer.java
Request.java
Response.java
HttpServer.java是程序的入口。它的main方法创建了一个HttpServer的实例,然后调用它的await方法,此方法等待客户端的
HTTP请求,处理请求,把响应传回客户端。此服务器程序只能处理静态的资源,如HTML文件和图片文件。
我们来看看HttpServer.java的源代码
Request.java类代表一个HTTP请求,它的构造方法传入一个InputStream输入流,该输入流来自于与客户端交流的那个socket,即ServerSocket的accept方法返回的那个socket对象。下面是Request.java类的源代码:
方法parse()用来解析HTTP请求的数据。方法parseUri()根据传入的请求数据(一个字符串)解析出HTTP请求的URI,如GET /index.html HTTP/1.1中的 /index.html
就是一个HTTP请求的URI,方法parseUri()是通过搜索请求的第一个空格和第二个空格间的字符串来得到URI的。
Response.java类代表一个HTTP响应,源代码如下:
Response类的构造方法传入一个OutputStream输出流,此输出流来自于socket的getOutputStream()方法,而此socket又来自于ServerSocket的accept方法返回的对象
Response类的sendStaticResource()方法先找到HTTP请求头的URI所代表的文件,将此文件读入到一个字节数组,再用OutputStream输出流将字节数组写入到客户端
的浏览器。如果URI所代表的文件不存在,就向浏览器写入一个错误信息。
启动HttpServer类,在浏览器中输入http://localhost:8080/index.html,(可以自己在此web工程的WebRoot根目录下新建一个index.html文件),你将看到index.html在浏览器
中显示出来。
我们的服务器程序由下列三个类组成:
HttpServer.java
Request.java
Response.java
HttpServer.java是程序的入口。它的main方法创建了一个HttpServer的实例,然后调用它的await方法,此方法等待客户端的
HTTP请求,处理请求,把响应传回客户端。此服务器程序只能处理静态的资源,如HTML文件和图片文件。
我们来看看HttpServer.java的源代码
import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; public class HttpServer { /** * WEB_ROOT是存放HTML文件的目录 */ public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot"; //关闭命令 private static final String SHUTDOWN_COMMAND = "/SHUTDOWN"; //收到关闭命令 private boolean shutdown = false; /** * @param args */ public static void main(String[] args) { HttpServer server = new HttpServer(); server.await(); } public void await() { 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(!shutdown){ Socket socket = null; InputStream inputStream = null; OutputStream outputStream = null; try{ socket = serverSocket.accept(); inputStream = socket.getInputStream(); outputStream = socket.getOutputStream(); //创建请求对象并解析 Request request = new Request(inputStream); request.parse(); //创建响应对象 Response response = new Response(outputStream); response.setRequest(request); response.sendStaticResource(); //关闭socket if(socket != null){ socket.close(); } //检查URI是否是一个关闭命令 shutdown = SHUTDOWN_COMMAND.equals(request.getUri()); }catch(Exception e){ e.printStackTrace(); continue; } } } }
Request.java类代表一个HTTP请求,它的构造方法传入一个InputStream输入流,该输入流来自于与客户端交流的那个socket,即ServerSocket的accept方法返回的那个socket对象。下面是Request.java类的源代码:
import java.io.IOException; import java.io.InputStream; public class Request { private InputStream inputStream; private String uri; public Request(InputStream inputStream) { this.inputStream = inputStream; } public void parse(){ StringBuffer request = new StringBuffer(2048); int i; byte[] buffer = new byte[2048]; try{ i = inputStream.read(buffer); }catch(IOException e){ e.printStackTrace(); i = -1; } for(int j=0;j<i;j++){ request.append((char)buffer[j]); } System.out.println(request.toString()); uri = parseUri(request.toString()); } 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; }else{ return null; } } public String getUri() { return uri; } public void setUri(String uri) { this.uri = uri; } }
方法parse()用来解析HTTP请求的数据。方法parseUri()根据传入的请求数据(一个字符串)解析出HTTP请求的URI,如GET /index.html HTTP/1.1中的 /index.html
就是一个HTTP请求的URI,方法parseUri()是通过搜索请求的第一个空格和第二个空格间的字符串来得到URI的。
Response.java类代表一个HTTP响应,源代码如下:
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; public class Response { private static final int BUFFER_SIZE = 1024; Request request; OutputStream outputStream; public Response(OutputStream outputStream) { this.outputStream =outputStream; } public void setRequest(Request request) { this.request = request; } public void sendStaticResource() throws IOException{ byte bytes[] = new byte[BUFFER_SIZE]; FileInputStream fis = null; try{ File file = new File(HttpServer.WEB_ROOT,request.getUri()); if(file.exists()){ fis = new FileInputStream(file); int ch = fis.read(bytes,0,BUFFER_SIZE); while(ch != -1){ outputStream.write(bytes, 0, ch); ch = fis.read(bytes,0,BUFFER_SIZE); } }else{ String errorMessage = "<h1>File not found</h1>"; outputStream.write(errorMessage.getBytes()); } }catch(Exception e){ System.out.println(e.toString()); }finally{ if(fis != null) fis.close(); } } }
Response类的构造方法传入一个OutputStream输出流,此输出流来自于socket的getOutputStream()方法,而此socket又来自于ServerSocket的accept方法返回的对象
Response类的sendStaticResource()方法先找到HTTP请求头的URI所代表的文件,将此文件读入到一个字节数组,再用OutputStream输出流将字节数组写入到客户端
的浏览器。如果URI所代表的文件不存在,就向浏览器写入一个错误信息。
启动HttpServer类,在浏览器中输入http://localhost:8080/index.html,(可以自己在此web工程的WebRoot根目录下新建一个index.html文件),你将看到index.html在浏览器
中显示出来。
相关文章推荐
- 自己动手编写tomcat服务器(二)
- 自己动手编写tomcat服务器(三)
- 深入学习Tomcat----自己动手写服务器(附服务器源码)
- 深入学习Tomcat----自己动手写服务器(附服务器源码)
- 深入学习Tomcat----自己动手写服务器(附服务器源码)
- 深入学习Tomcat----自己动手写服务器
- 深入学习Tomcat----自己动手写服务器(附服务器源码)
- [servlet]深入学习Tomcat----自己动手写服务器(附服务器源码)
- 浅析Tomcat----自己动手写服务器
- 深入学习Tomcat-自己动手写服务器(附服务器源码)
- 深入学习Tomcat----自己动手写服务器(附服务器源码)
- 深入学习Tomcat----自己动手写服务器(附服务器源码)
- 深入学习Tomcat----自己动手写服务器(附服务器源码)
- 深入学习Tomcat----自己动手写服务器(附服务器源码)
- 深入学习Tomcat----自己动手写服务器(附服务器源码)
- 自己动手搭建苹果推送Push服务器
- 自己动手编写一个VS插件(二)——理解OnConnection函数
- 自己动手编写嵌入式Bootloader之(1)
- 自己动手编写一个VS插件(五)
- TE6410之自己动手编写LED驱动