今天我们就仿照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. python接口测试之日志功能

    之前在简书中看了一篇关于日志功能的文档,供大家参考:https://www.jianshu.com/p/62f7b49b41e7 Python通过logging模块提供日志功能,所以直接导入即可 im ...

  2. Jenkins集成appium自动化测试(Windows篇)

    一,引入问题 自动化测试脚本绝大部分用于回归测试,这就需要制定执行策略,如每天.代码更新后.项目上线前定时执行,才能达到最好的效果,这时就需要进行Jenkins集成. 不像web UI自动化测试可以使 ...

  3. elk-架构图

     

  4. beego路由

    router.go package routersimport ( "beego01/controllers" "github.com/astaxie/beego&quo ...

  5. 配置通过Web网管登录交换机

    组网图形 图1 通过Web网管登录交换机组网图 通过Web网管登录交换机简介 Web网管是一种对交换机的管理方式,它利用交换机内置的Web服务器,为用户提供图形化的操作界面.用户可以从终端通过HTTP ...

  6. 干货分享:一键网络重装系统 - 魔改版(适用于Linux / Windows)

      简介 一键网络重装系统 - 魔改版,它可以通过Internet重新安装Linux和Windows以及常见的操作系统.例如:Linux(CentOS,Debian,Ubuntu.etc..),Win ...

  7. CopyTranslator安装与使用

    PDF 格式的文本,本质上是保证了在大部分设备上都能保持清晰完整的排版格式,但不利于进一步使用,但是 PDF 文档文字复制会包括回车键,文字粘粘和翻译都不方便.通常的做法就是,先转换成 Word 格式 ...

  8. Spring入门-----------------属性注入和对象注入

    属性注入即通过setter方法注入bean的属性或依赖对象. 属性注入使用<property>元素,使用name属性指定bean的属性的名称,value属性或<value>子节 ...

  9. css3滚动条样式美化

    关于滚动条的设计,需要用到css3的微元素,都列在下边吧(以Chrome内核webkit为例). -webkit-scrollbar     滚动条的整体轮廓,width表示纵向滚动条的宽度,heig ...

  10. 4G DTU数据传输终端的功能介绍

    4G DTU是基于4G网络的自动化数据传输终端,是一种物联网无线数据传输设备,使用公用运营商的4G网络为用户提供无线远距离数据传输功能,使用工业级32位的高性能通信处理器和工业级无线模块,以嵌入式实时 ...