读了两章的 How Tomcat Works
周一发现了一本书.How Tomcat Works 惯例先到豆瓣搜书评.结果书评出奇的好.然后下载了PDF.从简介中看,本书的每个章节都会不断的围绕怎么建造一个Tomcat讲解.我本人比较喜欢这种造轮子的书.原因很简单,比较笨.如果书中没有代码,很难从脑海中构件代码结构.可是万万没想到,看到第三章,就发现,书中的代码不全,完整的代码还要到GitHub下载.无奈只能放下这本好书.(个人觉得看书就是要了解本质,如果书中的源码不全,而是给出片段,剩下的还要到项目中找,我觉得你还不如让我去直接看Tomcat的源码.实名DISS,因为这件事昨晚都没睡好.)不过开卷有益,贴出来两段代码,安慰下自己.
本次代码都有注释,就不一一介绍了.
public class HttpServer { //C:\workspace\yourTomcat\src /webroot public static final String WEB_ROOT = System.getProperty("user.dir")+ File.separator+ "webroot"; //停止语句 private static final String SHUTDOWN_COMMAND="/SHUTDOWN"; //停止标识符 private boolean shutdown = false; /* * @author 顶风少年 * @date 2019/9/16 16:57 * @mail dfsn199703132038@foxmail.com * @throws * @param * @result void * @notify 监听请求 * version 1.0 */ 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 input = null; OutputStream output = null; try { //客户端发送请求这里则会监听到 socket = serverSocket.accept(); //获取输入流 input = socket.getInputStream(); //获取输出流 output = socket.getOutputStream(); //解析请求对象 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; } } } }
public class Request { private InputStream input; private String uri; public Request(InputStream input) { this.input = input; } /* * @author 顶风少年 * @date 2019/9/16 16:57 * @mail dfsn199703132038@foxmail.com * @throws * @param * @result void * @notify 解析请求内容 * version 1.0 */ 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; } //循环将字节放到String中 for (int j = 0; j < i; j++) { request.append((char) buffer[j]); } //解析请求资源路径 uri = parseUri(request.toString()); } /* * @author 顶风少年 * @date 2019/9/16 16:59 * @mail dfsn199703132038@foxmail.com * @throws * @param * @param requestString * @result java.lang.String * @notify 解析请求资源路径 * version 1.0 */ private String parseUri(String requestString) { //记录前两个空格,第一个空格和第二个空格之间是 请求路径 GET /SHUTDOWN HTTP/1.1 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; } /* * @author 顶风少年 * @date 2019/9/16 17:00 * @mail dfsn199703132038@foxmail.com * @throws * @param * @result java.lang.String * @notify 获取请求路径 * version 1.0 */ public String getUri() { return uri; } }
public class Response { private static final int BUFFER_SIZE = 1024; Request request; OutputStream output; public Response(OutputStream output) { this.output = output; } /* * @author 顶风少年 * @date 2019/9/16 17:01 * @mail dfsn199703132038@foxmail.com * @throws * @param * @param request * @result void * @notify 设置request * version 1.0 */ public void setRequest(Request request) { this.request = request; } /* * @author 顶风少年 * @date 2019/9/16 17:02 * @mail dfsn199703132038@foxmail.com * @throws * @param * @result void * @notify 相应资源 * version 1.0 */ 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); //如果读取到了内容 output.write("HTTP/1.1 200 OK\\r\\nContent-Type: text/html\r\n\r\n".getBytes()); while (ch != -1) { //将内容写入到响应体 output.write(bytes, 0, ch); //再次读取 ch = fis.read(bytes, 0, BUFFER_SIZE); } } else { //每一找到请求资源 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) { e.printStackTrace(); } finally { //关闭流 if (fis != null) { fis.close(); } } } }
说起来这是我加入博客园一来,第一次写带感情的文章.从16年6月认识java.到18年工作做得微信小程序,以及少量的java工作.再到今年的运维,偏向java.这几年,我一直不断的学习java.java基础的书看了三本.
其他的语言js,html,c++,c#包括sql.这么多语言来讲,我还是最喜欢java,起先写java就是写demo,工作后的一段时间写crud觉得十分无趣.在后来读了几本书,才知道原来在crud的工作中,也可以加入设计模式,编
程思想.以后的工作,我时常将一些模式,和一些设计写到工作中的crud代码中,力图让工作不在那么无趣,也让自己写的代码看上去优雅些.对于java只想说,不忘初心,方得始终.
最后希望明年我能找到一份真正的java开发工作.在这最后的几个月,我也将继续修炼内功.学习更多的招式.晚安!