一个简单的Web服务器-支持静态资源请求
目标
实现一个简单的Web服务器,能够根据HTTP请求的URL响应对应的静态资源,如果静态资源不存在则响应404。
HttpServer
使用ServerSocket实现的一个服务器,request根据socket.getInputStream()获取HTTP报文,response将响应写入socket.getOutputStream()中。
public class HttpServer { public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "webroot";
private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
private static final int PORT = 8899; public HttpServer() { } public static void main(String[] args) throws IOException { HttpServer httpServer = new HttpServer();
httpServer.service();
} public void service() throws IOException { ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("服务器启动:" + serverSocket);
while (true) {
try (Socket socket = serverSocket.accept()) {
System.out.println("客户端建立连接:" + socket);
Request request = new Request(socket.getInputStream());
if (Objects.isNull(request.getUri())) {
continue;
}
if (isShutdownComment(request)) { //如果是shutdown命令,则关闭服务器
break;
}
Response response = new Response(request, socket.getOutputStream());
response.sendStaticResource(); // 返回静态资源
System.out.println("客户端关闭连接:" + socket);
} catch (Exception e) {
e.printStackTrace();
}
}
} private boolean isShutdownComment(Request request) {
return Objects.equals(SHUTDOWN_COMMAND, request.getUri());
}
}
Request
读取输入流,获取HTTP报文,并从中解析出URL,Response会根据这个URL去读取对应的静态资源
public class Request { private InputStream inputStream; /**
* HTTP 报文
*/
private String message; /**
* HTTP 请求 URI
*/
private String uri; public Request(InputStream inputStream) throws IOException {
parse(inputStream);
} /**
* 从 inputStream 中读取出报文
*/
private void parse(InputStream inputStream) throws IOException { StringBuilder sb = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while (Objects.nonNull(line = reader.readLine())) {
sb.append(line).append("\n");
}
this.message = sb.toString();
this.uri = parseURI();
System.out.println("-------------------------------------------");
System.out.println(message);
System.out.println("-------------------------------------------");
} /**
* 从报文中解析出请求 uri
*
* @return
*/
private String parseURI() { int beginIndex = message.indexOf(" ");
int endIndex = message.indexOf(" ", beginIndex + 1);
if (beginIndex == -1 || endIndex == -1) {
return null;
}
return message.substring(beginIndex + 1, endIndex);
} public String getUri() {
return uri;
} public String getMessage() {
return message;
}
}
Response
调用 File staticResource = new File(HttpServer.WEB_ROOT, request.getUri()); 拿到对应的静态资源。
比如请求的url是 http://localhost:8899/index.html,则会去webRoot下面寻找index.html文件,如果文件不存在则返回404
public class Response { private static final String RETURN_404 = "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>"; private OutputStream outputStream;
private Request request; public Response(Request request, OutputStream outputStream) {
this.request = request;
this.outputStream = outputStream;
} /**
* 发送静态资源
*/
public void sendStaticResource() throws IOException { File staticResource = new File(HttpServer.WEB_ROOT, request.getUri()); //请求的静态资源路径
if (staticResource.exists()) { //静态资源存在则返回给客户端
try (FileInputStream fileInputStream = new FileInputStream(staticResource)) {
int b = 0;
while ((b = fileInputStream.read()) != -1) {
outputStream.write(b);
}
}
} else { //不存在返回404
outputStream.write(RETURN_404.getBytes());
}
outputStream.flush();
}
}
参考
1.《How Tomcat Works》 - Budi Kurniawan
一个简单的Web服务器-支持静态资源请求的更多相关文章
- 一个简单的Web服务器-支持Servlet请求
上接 一个简单的Web服务器-支持静态资源请求,这个服务器可以处理静态资源的请求,那么如何处理Servlet请求的呢? 判断是否是Servlet请求 首先Web服务器需要判断当前请求是否是Servle ...
- Tomcat剖析(一):一个简单的Web服务器
Tomcat剖析(一):一个简单的Web服务器 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三):连接器 ...
- 自己动手模拟开发一个简单的Web服务器
开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...
- 一个简单的web服务器
写在前面 新的一年了,新的开始,打算重新看一遍asp.net本质论这本书,再重新认识一下,查漏补缺,认认真真的过一遍. 一个简单的web服务器 首先需要引入命名空间: System.Net,关于网络编 ...
- 自己模拟的一个简单的web服务器
首先我为大家推荐一本书:How Tomcat Works.这本书讲的很详细的,虽然实际开发中我们并不会自己去写一个tomcat,但是对于了解Tomcat是如何工作的还是很有必要的. Servlet容器 ...
- [置顶] 在Ubuntu下实现一个简单的Web服务器
要求: 实现一个简单的Web服务器,当服务器启动时要读取配置文件的路径.如果浏览器请求的文件是可执行的则称为CGI程序,服务器并不是将这个文件发给浏览器,而是在服务器端执行这个程序,将它的标准输出发给 ...
- 利用 nodeJS 搭建一个简单的Web服务器(转)
下面的代码演示如何利用 nodeJS 搭建一个简单的Web服务器: 1. 文件 WebServer.js: //-------------------------------------------- ...
- 《深度解析Tomcat》 第一章 一个简单的Web服务器
本章介绍Java Web服务器是如何运行的.从中可以知道Tomcat是如何工作的. 基于Java的Web服务器会使用java.net.Socket类和java.net.ServerSocket类这两个 ...
- 如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1
原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app 作为一个i ...
随机推荐
- zabbix监控docker容器
1.环境说明 由于最近zabbix进行过一次迁移,所以zabbix-server系列采用docker方式安装,参考zabbix官网:https://github.com/zabbix/zabbix-d ...
- Oracle基础知识点——Oracle常用权限理解:SYSDBA、SYSOPER、Normal、dba、connect、resource
权限介绍 系统权限 含义:系统规定用户使用数据库的权限,系统权限是针对用户对数据库的操作而言(登录数据库:读取数据表.视图:删除数据库).它只是概念上的role,只是一种登录认证时的身份标识而已. S ...
- Linus 本尊也来了!为什么 KubeCon 越来越火了?
2015年11月,第一届 KubeCon 在美国旧金山开始的时候,还只是个200人的小会议,2019年的7月,KubeCon 第二次在中国举办,就有 3500 多位云原生和开源领域工程师齐聚一堂. 连 ...
- Autodesk 卸载工具,一键完全彻底卸载删除autodesk软件专门卸载工具
autodesk卸载工具(AUTO Uninstaller)是专门为了针对autodesk类软件卸载不干净而导致autodesk安装失败问题进行研发的autodesk一键卸载工具.现在虽然360或一些 ...
- 前端基础☞CSS
css的四种引入方式 1.行内式 行内式是在标记的style属性中设定CSS样式.这种方式没有体现出CSS的优势,不推荐使用. <p style="background-color: ...
- ros自定义消息
ros自定义消息可以根据自身项目需求定义和封装想要的数据类型和数据结构.具体可以参考维基百科关于ros自定义消息部分 这里我只是记录自定义消息的要点部分: 1.首先要在工作空间下功能包中创建一个msg ...
- jmeter循环取消今天所有的订单
结构 1.首先,添加JDBC Connection Configuration 2.其次添加JDBC request 添加循环控制器 循环控制器下方添加计数器 ${__V(reservationID_ ...
- android学习——Android Layout标签之-viewStub,requestFocus,merge,include
定义Android Layout(XML)时,有四个比较特别的标签是非常重要的,其中有三个是与资源复用有关,分别是<viewStub/>, <requestFocus />, ...
- 命名分组(?<name>....)
捕获组分为: 普通捕获组(Expression) 命名捕获组(?Expression) 普通捕获组 从正则表达式左侧开始,每出现一个左括号"("记做一个分组,分组编号从 1 开始. ...
- 手动实现如何从H264流中提取SPS/PPS信息
1,代码比较简单,可以直接用了.流的第一个NALU一定是SPS void get_sps_pps_nalu(uint8_t *data, int len, std::vector<uint8_t ...