学习tomcat的时候,我们只是编写一个实现Servlet(间接实现)简单的java类。但是容器却能把他变成一个服务,在这之前他还是一个普通的类,并不能接受http请求。只有容器加载类并调用init方法才会把他变成一个真正的servlet,这时候他才能接受请求返回响应。
那么容器究竟是怎么实现的呢,从上一篇文章我们利用socket编程实现了远程操作文件夹,同样的。tomcat也是封装了socket从而实现将servlet类变成servlet服务。只是最终的业务逻辑传到我们编写的servlet类来处理。下面我们来实现一个简单的web服务器,效果就是可以接受http请求并响应,先看效果图:网址中输入http:\\localhost:8080
后台打印信息,也就是请求信息
下面是源代码,共有三个类
HttServer:提供服务
Resquest:得到请求信息并解析
Response:返回信息(需要加入http响应头部,不然浏览器无法解析)
import java.io.*; import java.net.*; /** *我们的服务类,当运行这个类时会监听指定的端口 */ public class HttpServer { // 关闭标识 private static final String SHUTDOWN_COMMAND = "/SHUTDOWN"; // 是否关闭监听,根据URI判定 private boolean shutdown = false; public static void main(String[] args) { HttpServer server = new HttpServer(); server.await(); } public void await() { ServerSocket serverSocket = null; int port = 8080; try { //监听本地8080端口 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 input = null; OutputStream output = null; try { socket = serverSocket.accept(); input = socket.getInputStream(); output = socket.getOutputStream(); // 读取请求内容,包括http请求头,以及请求内容 Request request = new Request(input); request.parse(); // 做出响应 Response response = new Response(output); response.setRequest(request); response.sendStaticResource(); // 关闭socket socket.close(); //检查是否要关闭监听 shutdown = request.getUri().equals(SHUTDOWN_COMMAND); } catch (Exception e) { e.printStackTrace(); continue; } } } }
import java.io.*; /** * 解析请求内容 */ public class Request { private InputStream input; private String uri; public Request(InputStream input) { this.input = input; } public void parse() { StringBuffer 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.println("请求信息"+request.toString()); uri = parseUri(request.toString()); System.out.println("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 String getUri() { return uri; } }
import java.io.*; /** * 响应类 */ public class Response { private static final int BUFFER_SIZE = 1024; Request request; OutputStream output; public Response(OutputStream output) { this.output = output; } 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()); System.out.println(request.getUri()); File file = new File("F:\\howtomcatworks\\HowTomcatWorks\\webroot\\index.html"); System.out.println("文件已找到"); if (file.exists()) { String errorMessage = "HTTP/1.1 200 File Found\r\n" + "Content-Type: text/html\r\n" + "\r\n"+ "<h1>File Found</h1>"; output.write(errorMessage.getBytes()); } else { // file not found String errorMessage = "HTTP/1.1 404 File Not Found\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 23\r\n" + "\r\n" + "<h1>File Not Found</h1>"; output.write(errorMessage.getBytes()); } } catch (Exception e) { // thrown if cannot instantiate a File object System.out.println(e.toString() ); } finally { if (fis!=null) fis.close(); } } }