今天我们就仿照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. MeteoInfoLab脚本示例:计算涡度、散度

    用U/V分量数据计算涡度和散度,计算涡度的函数是hcurl,计算散度的函数是hdivg,参数都是U, V.脚本程序: f = addfile('D:/Temp/GrADS/model.ctl') u ...

  2. 发布MeteoInfo 1.2.3

    提升了对GeoTiff格式数据的读取能力(多个tiles).当然还有MeteoInfoLab功能的提升.下载地址:http://yun.baidu.com/share/link?shareid=669 ...

  3. 串口wifi

    串口wifi 串口WiFi ZLAN7146是一款wifi转串口的wifi串口服务器.该串口服务器可以方便地使得串口设备连接到WIFI无线网络,实现串口设备的无线化网络升级.RS232接口支持全双工. ...

  4. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU硬件那些事(2.4)- 串行NOR Flash下载算法(Keil MDK工具篇)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是Keil MDK工具下i.MXRT的串行NOR Flash下载算法设计. 在i.MXRT硬件那些事系列之<在串行NOR Flash ...

  5. pmm-server 搭建

    1 搭建docker centos 下 参考文档搭建docker  https://www.cnblogs.com/brady-wang/p/11543237.html docker create \ ...

  6. linux(centos8):安装prometheus服务端/node_exporter客户端(prometheus 2.18.1)

    一,prometheus的用途 Prometheus是一个开源的系统监控和警报工具包 相比其他监控系统,它更适用于微服务的体系架构 它使用各种专用exporter,用来实现对硬件/存储/数据库/web ...

  7. linux(fedora30):安装/配置maven(maven3.6.1)

    一,maven的用途 1,用途 Maven 是一个项目管理工具,主要用于项目构建,依赖管理,项目信息管理 maven可以用来: 帮用户下载jar包, 有依赖包时自动下载所需的依赖包 打包war包或ja ...

  8. centos8上安装ImageMagick6.9.10并压缩图片生成webp缩略图

    一,ImageMagick的作用: ImageMagick 是一个用来创建.编辑.合成图片的软件. 它可以读取.转换.写入多种格式的图片. 功能包括:图片切割.颜色替换.各种效果的应用, 图片的旋转. ...

  9. __getattr__和__setattr__

    getattr 拦截运算(obj.xx),对没有定义的属性名和实例,会用属性名作为字符串调用这个方法 class F(object): def __init__(self): self.name = ...

  10. Java9系列第7篇:Java.util.Optional优化与增强

    我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注.期待您能关注我,我将把java 9 ...