目标

实现一个简单的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服务器-支持静态资源请求的更多相关文章

  1. 一个简单的Web服务器-支持Servlet请求

    上接 一个简单的Web服务器-支持静态资源请求,这个服务器可以处理静态资源的请求,那么如何处理Servlet请求的呢? 判断是否是Servlet请求 首先Web服务器需要判断当前请求是否是Servle ...

  2. Tomcat剖析(一):一个简单的Web服务器

    Tomcat剖析(一):一个简单的Web服务器 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三):连接器 ...

  3. 自己动手模拟开发一个简单的Web服务器

    开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...

  4. 一个简单的web服务器

    写在前面 新的一年了,新的开始,打算重新看一遍asp.net本质论这本书,再重新认识一下,查漏补缺,认认真真的过一遍. 一个简单的web服务器 首先需要引入命名空间: System.Net,关于网络编 ...

  5. 自己模拟的一个简单的web服务器

    首先我为大家推荐一本书:How Tomcat Works.这本书讲的很详细的,虽然实际开发中我们并不会自己去写一个tomcat,但是对于了解Tomcat是如何工作的还是很有必要的. Servlet容器 ...

  6. [置顶] 在Ubuntu下实现一个简单的Web服务器

    要求: 实现一个简单的Web服务器,当服务器启动时要读取配置文件的路径.如果浏览器请求的文件是可执行的则称为CGI程序,服务器并不是将这个文件发给浏览器,而是在服务器端执行这个程序,将它的标准输出发给 ...

  7. 利用 nodeJS 搭建一个简单的Web服务器(转)

    下面的代码演示如何利用 nodeJS 搭建一个简单的Web服务器: 1. 文件 WebServer.js: //-------------------------------------------- ...

  8. 《深度解析Tomcat》 第一章 一个简单的Web服务器

    本章介绍Java Web服务器是如何运行的.从中可以知道Tomcat是如何工作的. 基于Java的Web服务器会使用java.net.Socket类和java.net.ServerSocket类这两个 ...

  9. 如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1

    原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app 作为一个i ...

随机推荐

  1. bzoj1579 道路升级

    Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i ...

  2. bzoj1624 寻宝之路

    Description     农夫约翰正驾驶一条小艇在牛勒比海上航行.     海上有N(1≤N≤100)个岛屿,用1到N编号.约翰从1号小岛出发,最后到达N号小岛.一张藏宝图上说,如果他的路程上经 ...

  3. Puppet基础

    基础架构图介绍 自动化运维框架:  自动化监控: puppet介绍 常用的批量工具介绍: OS Provisioning:PXE,Cobbler OS Configuration:ansible,pu ...

  4. framework7日期插件使用

    1.引入框架文件 <link rel="stylesheet" href="framework7.ios.min.css"> <link re ...

  5. oracle使用profile管理用户口令

    概述:profile是口令限制.资源限制的命令集合,当建立数据时,oracle会自动建立名称为default的profile,当建立用户没有指定profile选项,那么oracle就会将default ...

  6. mysql中int、bigint、smallint 和 tinyint

    bigint 从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807) 的整型数据(所有数字).存储大小为 8 个字节. int 从 ...

  7. C++返回值优化

    返回值优化(Return Value Optimization,简称RVO)是一种编译器优化机制:当函数需要返回一个对象的时候,如果自己创建一个临时对象用于返回,那么这个临时对象会消耗一个构造函数(C ...

  8. 修改UISearchBar背景

    转载:http://blog.csdn.net/favormm/archive/2010/11/30/6045463.aspx UISearchBar是由两个subView组成的,一个是UISearc ...

  9. uni-app获取当前位置

    uniapp获取当前城市: 官方api:uni.getLocation()获取当前的地理位置.速度. 在微信小程序中,当用户离开应用后,此接口无法调用,除非申请后台持续定位权限:当用户点击“显示在聊天 ...

  10. python selenium处理iframe和弹框(一)

    处理iframe和弹框 # encoding:utf-8 from selenium import webdriver import time driver = webdriver.Firefox() ...