今天我们就仿照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服务器的更多相关文章

  1. 手写一套迷你版HTTP服务器

    本文主要介绍如何通过netty来手写一套简单版的HTTP服务器,同时将关于netty的许多细小知识点进行了串联,用于巩固和提升对于netty框架的掌握程度. 服务器运行效果 服务器支持对静态文件css ...

  2. 『练手』手写一个独立Json算法 JsonHelper

    背景: > 一直使用 Newtonsoft.Json.dll 也算挺稳定的. > 但这个框架也挺闹心的: > 1.影响编译失败:https://www.cnblogs.com/zih ...

  3. 看年薪50W的架构师如何手写一个SpringMVC框架

    前言 做 Java Web 开发的你,一定听说过SpringMVC的大名,作为现在运用最广泛的Java框架,它到目前为止依然保持着强大的活力和广泛的用户群. 本文介绍如何用eclipse一步一步搭建S ...

  4. webview的简单介绍和手写一个H5套壳的webview

    1.webview是什么?作用是什么?和浏览器有什么关系? Webview 是一个基于webkit引擎,可以解析DOM 元素,展示html页面的控件,它和浏览器展示页面的原理是相同的,所以可以把它当做 ...

  5. 手把手教你手写一个最简单的 Spring Boot Starter

    欢迎关注微信公众号:「Java之言」技术文章持续更新,请持续关注...... 第一时间学习最新技术文章 领取最新技术学习资料视频 最新互联网资讯和面试经验 何为 Starter ? 想必大家都使用过 ...

  6. 手写一个虚拟DOM库,彻底让你理解diff算法

    所谓虚拟DOM就是用js对象来描述真实DOM,它相对于原生DOM更加轻量,因为真正的DOM对象附带有非常多的属性,另外配合虚拟DOM的diff算法,能以最少的操作来更新DOM,除此之外,也能让Vue和 ...

  7. 一个简单的Java web服务器实现

    前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...

  8. 教你如何使用Java手写一个基于链表的队列

    在上一篇博客[教你如何使用Java手写一个基于数组的队列]中已经介绍了队列,以及Java语言中对队列的实现,对队列不是很了解的可以我上一篇文章.那么,现在就直接进入主题吧. 这篇博客主要讲解的是如何使 ...

  9. 【spring】-- 手写一个最简单的IOC框架

    1.什么是springIOC IOC就是把每一个bean(实体类)与bean(实体了)之间的关系交给第三方容器进行管理. 如果我们手写一个最最简单的IOC,最终效果是怎样呢? xml配置: <b ...

随机推荐

  1. 【贪心算法】CF Emergency Evacuation

    题目大意 vjudge链接 给你一个车厢和一些人,这些人都坐在座位上,求这些人全部出去的时间最小值. 样例1输入 5 2 71 11 21 32 32 44 45 2 样例1输出 9 样例2输入 50 ...

  2. linux-查看内核

    [root@localhost vagrant]# uname -r 3.10.0-1127.19.1.el7.x86_64   [root@localhost vagrant]# cat /etc/ ...

  3. ffmpeg实现视频文件合并/截取预览视频/抽取音频/crop(裁剪)(ffmpeg4.2.2)

    一,ffmpeg的安装 请参见: https://www.cnblogs.com/architectforest/p/12807683.html 说明:刘宏缔的架构森林是一个专注架构的博客,地址:ht ...

  4. RabbitMQ消息队列总结

    AMQP[高级消息队列协议] 是一个异步消息传递所使用的应用层协议规范(是线路层协议)AMQP 客户端能够无视消息的来源任意发送和接受信息 队列的使用场景: 1.与业务的主要逻辑无关,但又需要执行,就 ...

  5. 聊聊简单又灵活的权限设计(RBAC)

    你:我看完能知道个啥?我:也就以下两点吧一. 了解基于 RBAC 思路的表设计二. 表数据在实际开发场景中是如何使用的你:我觉得那应该还有点干货吧我:我不要你觉得,我要我觉得 (͡ ͡° ͜ つ ͡͡ ...

  6. 用Hugo在gitee上构建博客(Windows环境下)

    目录 用Hugo在gitee上构建博客(Windows环境下) 1.为什么要用gitee? 2.安装git 3.安装Hugo 4.创建远程仓库 5.搭建博客 (以下所有命令都在git bash中输入) ...

  7. Linux入门到放弃之八《任务计划管理》

    任务计划管理 1.每周一下午5:50将/data目录下的所有目录和文件归档并压缩为:backup.tar.gz 放在/home/backup目录下. 先新建/data目录,并在目录中随意生成几个文件 ...

  8. cao 啥时候能系统地复习一下数据结构 我光学数学去了

    最近有功夫的话再敲敲数据结构复习复习

  9. Zotero导入Markdown here插件

    1. 下载Markdown Here源码包 网址:https://github.com/adam-p/markdown-here 2. 创建.xpi后缀文件 将文件夹 中的这几个文件放入同一个文件夹中 ...

  10. Chrome FeHelper 插件下载地址

    方便大家下载 下载可用,本人亲自测试 下载地址: 地址链接