手写一个最迷你的Web服务器
今天我们就仿照Tomcat服务器来手写一个最简单最迷你版的web服务器,仅供学习交流。
1. 在你windows系统盘的F盘下,创建一个文件夹webroot,用来存放前端代码。
2. 代码介绍:
(1)ServerThread.java 核心代码,主要用于web文件的读取与解析等。代码如下:
1 package server;
2
3 import java.io.*;
4 import java.net.Socket;
5 import java.util.Date;
6 import java.util.HashMap;
7 import java.util.Map;
8
9 /**
10 * @ClassName: ServerThread
11 * @Description:
12 * @Author: liuhefei
13 * @Date: 2019/6/23
14 * @blog: https://www.imooc.com/u/1323320/articles
15 **/
16 public class ServerThread implements Runnable {
17
18 private static Map<String, String> contentMap = new HashMap<>();
19
20 //可以参照Tomcat的web.xml配置文件
21 static {
22 contentMap.put("html", "text/html");
23 contentMap.put("htm", "text/html");
24 contentMap.put("jpg", "image/jpeg");
25 contentMap.put("jpeg", "image/jpeg");
26 contentMap.put("gif", "image/gif");
27 contentMap.put("js", "application/javascript");
28 contentMap.put("css", "text/css");
29 contentMap.put("json", "application/json");
30 contentMap.put("mp3", "audio/mpeg");
31 contentMap.put("mp4", "video/mp4");
32 }
33
34 private Socket client;
35 private InputStream in;
36 private OutputStream out;
37 private PrintWriter pw;
38 private BufferedReader br;
39
40 private static final String webroot = "F:\\webroot\\"; //此处目录,你可以自行修改
41
42 public ServerThread(Socket client){
43 this.client = client;
44 init();
45 }
46
47 private void init(){
48 //获取输入输出流
49 try {
50 in = client.getInputStream();
51 out = client.getOutputStream();
52 } catch (IOException e) {
53 e.printStackTrace();
54 }
55
56 }
57
58 @Override
59 public void run() {
60 try {
61 gorun();
62 } catch (Exception e) {
63 e.printStackTrace();
64 }
65 }
66
67 private void gorun() throws Exception {
68 //读取请求内容
69 BufferedReader reader = new BufferedReader(new InputStreamReader(in));
70 String line = reader.readLine().split(" ")[1].replace("/", "\\"); //请求的资源
71 if(line.equals("\\")){
72 line += "index.html";
73 }
74 System.out.println(line);
75 String strType = line.substring(line.lastIndexOf(".")+1, line.length()); //获取文件的后缀名
76 System.out.println("strType = " + strType);
77
78 //给用户响应
79 PrintWriter pw = new PrintWriter(out);
80 InputStream input = new FileInputStream(webroot + line);
81
82 //BufferedReader buffer = new BufferedReader(new InputStreamReader(input));
83 pw.println("HTTP/1.1 200 ok");
84 pw.println("Content-Type: "+ contentMap.get(strType) +";charset=utf-8");
85 pw.println("Content-Length: " + input.available());
86 pw.println("Server: hello");
87 pw.println("Date: " + new Date());
88 pw.println();
89 pw.flush();
90
91 byte[] bytes = new byte[1024];
92 int len = 0;
93 while ((len = input.read(bytes)) != -1){
94 out.write(bytes, 0, len);
95 }
96 pw.flush();
97
98 input.close();
99 pw.close();
100 reader.close();
101 out.close();
102
103 client.close();
104 }
105 }
(2)HttpServer.java (普通版)服务端
1 package server;
2
3 import java.io.*;
4 import java.net.ServerSocket;
5 import java.net.Socket;
6 import java.util.Date;
7
8 /**
9 * @ClassName: HttpServer
10 * @Description: 服务端
11 * @Author: liuhefei
12 * @Date: 2019/6/23
13 * @blog: https://www.imooc.com/u/1323320/articles
14 **/
15 public class HttpServer {
16 public static void main(String[] args) throws IOException {
17 //启动服务器,监听9005端口
18 ServerSocket server = new ServerSocket(9005);
19 System.out.println("服务器启动,监听9005端口....");
20 while (!Thread.interrupted()){
21 //不停接收客户端请求
22 Socket client = server.accept();
23 //开启线程
24 new Thread(new ServerThread(client)).start();
25 }
26 server.close();
27 }
28 }
(2)HttpServer1.java (线程池版)服务端
1 package server;
2
3 import java.io.IOException;
4 import java.net.ServerSocket;
5 import java.net.Socket;
6 import java.util.concurrent.ExecutorService;
7 import java.util.concurrent.Executors;
8
9 /**
10 * @ClassName: HttpServer
11 * @Description: 服务端
12 * @Author: liuhefei
13 * @Date: 2019/6/23
14 * @blog: https://www.imooc.com/u/1323320/articles
15 **/
16 public class HttpServer1 {
17 public static void main(String[] args) throws IOException {
18 //创建线程池
19 ExecutorService pool = Executors.newCachedThreadPool();
20
21 //启动服务器,监听9005端口
22 ServerSocket server = new ServerSocket(9005);
23 System.out.println("服务器启动,监听9005端口....");
24 while (!Thread.interrupted()){
25 //不停接收客户端请求
26 Socket client = server.accept();
27 //向线程池中提交任务
28 pool.execute(new ServerThread(client));
29 }
30 server.close();
31 pool.shutdown();
32 }
33 }
3. 将一个具有index.html的静态页面文件拷入到我们创建的webroot目录下。相关的静态web资源代码可以到源码之家下载或是自己编写。
4. 启动web服务,启动HttpServer.java 或HttpServer1.java都可以,服务启动之后将会监听9005端口。
5. 我们到浏览器上访问我们的服务,访问地址:http://localhost:9005/index.html,
手写一个最迷你的Web服务器的更多相关文章
- 手写一套迷你版HTTP服务器
本文主要介绍如何通过netty来手写一套简单版的HTTP服务器,同时将关于netty的许多细小知识点进行了串联,用于巩固和提升对于netty框架的掌握程度. 服务器运行效果 服务器支持对静态文件css ...
- 『练手』手写一个独立Json算法 JsonHelper
背景: > 一直使用 Newtonsoft.Json.dll 也算挺稳定的. > 但这个框架也挺闹心的: > 1.影响编译失败:https://www.cnblogs.com/zih ...
- 看年薪50W的架构师如何手写一个SpringMVC框架
前言 做 Java Web 开发的你,一定听说过SpringMVC的大名,作为现在运用最广泛的Java框架,它到目前为止依然保持着强大的活力和广泛的用户群. 本文介绍如何用eclipse一步一步搭建S ...
- webview的简单介绍和手写一个H5套壳的webview
1.webview是什么?作用是什么?和浏览器有什么关系? Webview 是一个基于webkit引擎,可以解析DOM 元素,展示html页面的控件,它和浏览器展示页面的原理是相同的,所以可以把它当做 ...
- 手把手教你手写一个最简单的 Spring Boot Starter
欢迎关注微信公众号:「Java之言」技术文章持续更新,请持续关注...... 第一时间学习最新技术文章 领取最新技术学习资料视频 最新互联网资讯和面试经验 何为 Starter ? 想必大家都使用过 ...
- 手写一个虚拟DOM库,彻底让你理解diff算法
所谓虚拟DOM就是用js对象来描述真实DOM,它相对于原生DOM更加轻量,因为真正的DOM对象附带有非常多的属性,另外配合虚拟DOM的diff算法,能以最少的操作来更新DOM,除此之外,也能让Vue和 ...
- 一个简单的Java web服务器实现
前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...
- 教你如何使用Java手写一个基于链表的队列
在上一篇博客[教你如何使用Java手写一个基于数组的队列]中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章.那么,现在就直接进入主题吧. 这篇博客主要讲解的是如何使 ...
- 【spring】-- 手写一个最简单的IOC框架
1.什么是springIOC IOC就是把每一个bean(实体类)与bean(实体了)之间的关系交给第三方容器进行管理. 如果我们手写一个最最简单的IOC,最终效果是怎样呢? xml配置: <b ...
随机推荐
- Verilog基础入门——简单的语句块编写(一)
[题干] [代码] module top_module ( input in, output out ); assign out = ~in; endmodule 简单的实现一个非门
- 【数论】HAOI2012 容易题
题目大意 洛谷链接 有一个数列A已知对于所有的\(A[i]\)都是\(1~n\)的自然数,并且知道对于一些\(A[i]\)不能取哪些值,我们定义一个数列的积为该数列所有元素的乘积,要求你求出所有可能的 ...
- 安装JDK及环境变量配置
1.下载JDK: 下载地址:https://www.oracle.com/technetwork/java/javase/overview/index.html 2.解压,运行安装包,下一步,选择安装 ...
- 全球首个优秀的华人.net微服务框架 作者:百大僧
话不多说,直接上地址 https://gitee.com/shoubashou/NetCoreMicroService,目标斩获10000star, 通往牛逼的路上,风景差得让人只说脏话. 是全球首个 ...
- catch之后的代码什么时候执行
1.若catch(){}块中,如果有throw 语句,则,try{}catch(){} finally{}块之外的代码不执行: 否则,执行. 2.try{}中有异常,则异常下面代码不执行. 3.fin ...
- 执行java -jar filename.jar提示没有主清单属性
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> ...
- Deployer 的使用
假设我们的项目在本地 /www/demo-project 下,那么我们切换到该目录: $ cd /www/demo-project 然后执行 Deployer 的初始化命令: $ dep init 它 ...
- 【原创】linux实时操作系统xenomai x86平台基准测试(benchmark)
一.前言 benchmark 即基准测试.通常操作系统主要服务于应用程序,其运行也是需要一定cpu资源的,一般来说操作系统提供服务一定要快,否则会影响应用程序的运行效率,尤其是实时操作系统.所以本文针 ...
- oblivious polynomial evaluation
Oblivious polynomial evaluation is a protocol involving two parties, a sender whose input is a polyn ...
- MapReduce工作原理详解
文章概览: 1.MapReduce简介 2.MapReduce有哪些角色?各自的作用是什么? 3.MapReduce程序执行流程 4.MapReduce工作原理 5.MapReduce中Shuffle ...