一个简单的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 ...
随机推荐
- 【JZOJ4846】【NOIP2016提高A组集训第5场11.2】行走
题目描述 数据范围 对于70%的数据保证 n <= 1000 对于100%的数据保证 n,q <= 10^5,c_i,v_i <= 10^{18} 保证每次修改后的边权小于等于原来的 ...
- 前端web设置div宽高一样
<div class="constant-width-to-height-ratio"></div> .constant-width-to-height-r ...
- hdu 6197 2017 ACM/ICPC Asia Regional Shenyang Online array array array【最长不上升子序列和最长不下降子序列】
hdu 6197 题意:给定一个数组,问删掉k个字符后数组是否能不减或者不增,满足要求则是magic array,否则不是. 题解:队友想的思路,感觉非常棒!既然删掉k个后不增或者不减,那么就先求数组 ...
- cume_dist(),名次分析——-最大排名/总个数
函数:cume_dist() over(order by id) select id,area,score, cume_dist() over(order by id) a, --按ID最大排名/总个 ...
- SDUT-2117_数据结构实验之链表二:逆序建立链表
数据结构实验之链表二:逆序建立链表 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入整数个数N,再输入N个整数,按照 ...
- js this详解
This的定义: 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用. this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是 ...
- Libev源码分析08:Libev中的信号监视器
Libev中的信号监视器,用于监控信号的发生,因信号是异步的,所以Libev的处理方式是尽量的将异步信号同步化.异步信号的同步化方法主要有:signalfd.eventfd.pipe.sigwaiti ...
- PHP怎么调用其他类的方法
2个PHP,这个PHP中的类调用另一个PHP中的类,如何调用.Java中是import ,php中是什么?还是用其他什么方法? 1.引用类:比如类名为product,则:include('...路径/ ...
- Python 基础09 面向对象的进一步拓展
调用类的其他信息 上一讲中提到,在定义方法时,必须有self这一个参数,这个参数表示某个对象,对象有有类的所有性质, 那么我么可以通过self 调用类属性. class Human(object): ...
- [ Laravel 5.6 文档 ] 安全系列 —— 重置密码
http://laravelacademy.org/post/8929.html 简介 想要快速实现该功能?只需要在新安装的 Laravel 应用下运行 php artisan make:auth(如 ...