一个简单的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 ...
随机推荐
- 阿里巴巴资深技术专家无相:我们能从 InteliJ IDEA 中学到什么?
本文来源于阿里巴巴资深技术专家无相在内网的分享,阿里巴巴中间件受权发布. 最近因为工作的关系,要将 Eclipse 的插件升级为 IDEA 插件.升级过程中,对 IDEA 插件做了些学习和研究,希望通 ...
- 网络流24题 餐巾计划(DCOJ8008)
题目描述 一个餐厅在相继的 n nn 天里,每天需用的餐巾数不尽相同.假设第 i ii 天需要 ri r_iri 块餐巾.餐厅可以购买新的餐巾,每块餐巾的费用为 P PP 分:或者把旧餐巾送到快 ...
- 使用php simple html dom parser解析html标签
转自:http://www.blhere.com/1243.html 使用php simple html dom parser解析html标签 用了一下 PHP Simple HTML DOM Par ...
- 【时光回溯】【JZOJ3568】【GDKOI2014】小纪的作业题
题目描述 输入 输出 有M行,每个询问一行,输出结果mod 1,000,000,007的值. 样例输入 10 3 3 5 1 2 3 1 3 5 2 1 7 9 3 9 2 3 样例输出 10 19 ...
- C++:for范围循环特点--自我理解
for(declaration : expression)statement for(xx-type i : P)....其一:for范围类型循环在循环前,可能会对p所在的队列里,对每一个对象进行一次 ...
- 百度语音识别REST API用法(含JAVA代码)——不须要集成SDK的方法
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zpf8861/article/details/32329457 上一篇文章http://blog.c ...
- 2019-10-21-WPF-多个-StylusPlugIn-的事件触发顺序
title author date CreateTime categories WPF 多个 StylusPlugIn 的事件触发顺序 lindexi 2019-10-21 08:33:15 +080 ...
- select引起的服务端程序崩溃问题
现象: 某个线上的服务最近频繁崩溃.该服务使用C++编写,是个网络服务端程序.作为TCP服务端,接收和转发客户端发来的消息,并给客户端发送消息.该服务跑在CentOS上,8G内存.线上环境中,与客户端 ...
- poj 2828【线段树 单点更新】
POJ 2828 还是弱啊.思维是个好东西... 刚开始想来想去用线段树存人的话不仅超时,而且存不下...居然是存空位! sum[]数组存这个序列空位个数,然后逆序遍历.逆序好理解,毕竟最后一个人插进 ...
- Codeforces Round #591 (Div. 2, based on Technocup 2020 Elimination Round 1) 题解
A..B略 C 对当前的值排序,再二分答案,然后对于(i%x==0 && i%y==0)放入大的,再放其他的贪心解决即可. #include<iostream> #incl ...