一个简单的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 ...
随机推荐
- More Effective C++: 03异常
C++的异常机制使得程序付出某些代价:资源泄漏的可能性增加了:写出具有你希望的行为的构造函数与析构函数变得更加困难:执行程序和库程序尺寸增加了,同时运行速度降低了等等. 但是为什么使用异常呢?C程序使 ...
- MongoDB负载信息一目了然 阿里云HDM重磅发布MongoDB监控和诊断功能
混合云数据库管理(HDM)的统一监控.告警.诊断功能新增了对MongoDB的支持. 通过直观的方式将MongoDB多个维度的负载信息统一整合,不仅可以清晰的查看实时负载信息,也可以方便的确认历史负载情 ...
- centos6.5后台进程的切换
1.运行.sh文件 直接用./sh 文件就可以运行,但是如果想后台运行,即使关闭当前的终端也可以运行的话,需要nohup命令和&命令. (1)&命令 功能:加在一个命令的最后,可以把这 ...
- 【JZOJ4886】【NOIP2016提高A组集训第13场11.11】字符串
题目描述 某日mhy12345在教同学们写helloworld,要求同学们用程序输出一个给定长度的字符串,然而发现有些人输出了一些"危险"的东西,所以mhy12345想知道对于任意 ...
- String字符串的比较 Day15
package com.sxt.review; /* * String字符串的比较 * ==和equals() * 总结:比较String内容时用equals()方法 */ public class ...
- oracle使用profile管理用户口令
概述:profile是口令限制.资源限制的命令集合,当建立数据时,oracle会自动建立名称为default的profile,当建立用户没有指定profile选项,那么oracle就会将default ...
- linux更新系统时间
查看时间 date 更新时间 yum install ntpdate ntpdate time.windows.com
- H3C 常用接口和线缆
- SuperSocket通过证书文件启用 TLS/SSL
你需要通过下面的步骤修改配置文件来使用你准备好的证书文件: 在server节点设置security属性: 在server节点下增加certificate子节点: 最后配置应该像这样: <serv ...
- MongonDB指令汇总
MongoDB特点使用不存在的对象,就等于你在创建这个对象(库,表,记录) MongoDB服务器/客户端相关 (记得把配置环境变量bin,MongonDB安装后bin在C盘的programfile-- ...