更新:现在的tomcat已经可以实现调用servlet中的service()方法了,把在这个阶段遇到的问题总结一下。
1.在对网页进行访问时,访问会请求2次。第二次是请求/favicon.ico(网页图标)这个东西。(不知道是每个浏览器都会还是个别才有),因为测试的index.html等网页是没有设这个图标的,所以第二次请求会导致抛很多错。在项目中放个图片进去就好了。
2.在servlet调用service(request,response)方法后,如果不进行outputstream.close(),write()的内容不会到网页上,而且会显示“网页重定向”。
查了一下相关文档,当socket中的outpustream关闭时会把这个socket也关掉,但是为什么要在特定的地方close才可以呢??
—————————————————————————更新分界线—————————————————————————
这个简单版tomcat现在是只能处理静态资源的,它用自定义的request和response模拟tomcat接收到客户请求后把请求的静态资源返回给客户端的过程。
通过写了这个东西(虽然刚开始看了很多别人的代码),但是对于tomcat的处理机制终于有了一点简单的了解。以及,tomcat是每个客户端都开一个线程的。
项目结构图:
request作用:解析http请求,把其中的请求资源地址拿出来(例如"hello.html")。
response作用:把指定的uri中的资源找到,然后返回给客户端。
遇到的问题
1.request中读取http请求的时候,如果用以下的方式
while ((count =bufferedReader.read(buffer,0,1024)) != -1){
stringBuilder.append(buffer);
}
则启动时,会报“socket write error”。
问题原因:inputstream的read()方法,只有当到达流结尾才会返回-1,否则它会阻塞等待数据;但是socket未被关闭时,它不会关闭inpustream,所以read()方法无法结束。故这里的read()会一直阻塞。
解决方法之一可以用InpuStream.avalable()来同时判断(这个方法会在socket的inpustream中没有数据时返回0)
2.注意serversocket和socket的放置位置
public static void main(String[] args){
try (ServerSocket serverSocket = new ServerSocket(8080,1, InetAddress.getByName("127.0.0.1"))){
while (true){
Socket socket = serverSocket.accept();
Thread thread = new Thread(new ServerThread(socket));
thread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
我做了两种操作,1,把serversocket放到了ServerThread的构造函数;2,把socket放到ServerThread的构造函数。
第一种做法中,我的电脑黑屏了。第一种做法中,它会无限量地创建线程,然后执行。因为serverSocket刚开始就创建了,一直存在。第二种做法中,它会在有服务请求的时候创建线程,并且执行。因为要在serversocket检测到有客户请求的时候,才会返回一个socket。
3.注意关闭资源,及时回收哦。