前言

文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206种一棵树最好的时间是十年前,其次是现在

six-finger-web

一个Web后端框架的轮子从处理Http请求【基于Netty的请求级Web服务器】 到mvc【接口封装转发)】,再到ioc【依赖注入】,aop【切面】,再到 rpc【远程过程调用】最后到orm【数据库操作】全部自己撸一个(简易)的轮子。

https://github.com/bin392328206/six-finger-web

为啥要写这个轮子

其实是这样的,小六六自己平时呢?有时候喜欢看看人家的源码比如Spring,但是小六六的水平可能不怎么样,每次看都看得晕头转向,然后就感觉里面的细节太难了,然后我就只能观其总体的思想,然后我就想我如果可以根据各位前辈的一些思考,自己撸一个简单的轮子出来,那我后面去理解作者的思想是不是简单点呢?于是呢 six-finger-web就面世了,它其实就是我的一个学习过程,然后我把它开源出来,希望能帮助那些对于学习源码有困难的同学。还有就是可以锻炼一下自己的编码能力,因为平时我们总是crud用的Java api都是那些,久而久之,很多框架类的api我们根本就不熟练了,所以借此机会,锻炼一下。

特点

  • 内置由 Netty 编写 HTTP 服务器,无需额外依赖 Tomcat 之类的 web 服务(刚好小六六把Netty系列写完,顺便用下)
  • 代码简单易懂(小六六自己写不出框架大佬那种高类聚,低耦合的代码),能力稍微强一点看代码就能懂,弱点的也没关系,小六六有配套的从0搭建教程。
  • 支持MVC相关的注解确保和SpringMVC的用法类似
  • 支持Spring IOC 和Aop相关功能
  • 支持类似于Mybatis相关功能
  • 支持类似于Dubbo的rpc相关功能
  • 对于数据返回,只支持Json格式

絮叨

此教程只适合初中级水平,因为作者本身水平不高,不喜勿喷,今天是文章的第一篇,所以先写的是 由Netty 搭建一个http服务器

使用Netty实现HTTP服务器

Netty是一个异步事件驱动的网络应用程序框架用于快速开发可维护的高性能协议服务器和客户端。Netty经过精心设计,具有丰富的协议,如FTP,SMTP,HTTP以及各种二进制和基于文本的传统协议。

Java程序员在开发web应用的时候,我们习惯于基于servlet规范,来做后端开发,就比如我们的SpringMVC其本质也是一个servlet,至于spring Webfux,我不知道有多少公司使用了,但是目前为止2020,我们公司是没有使用的,这次呢我们就试试用Netty来实现一下,其实这个很简单,以前的我写Netty系列的时候,我已经写过了,大家可以去找找https://github.com/bin392328206/six-finger

首先是创建项目

因为我们这个是six-finger-web的第一篇,所以我尽量把点点滴滴做到

首先创建一个maven项目,如果这个都不会的话,小六六建议先学习基础再来,在文章很多的地方,一些基础的小六六是默认你懂,如果有啥不懂的可以上github上找我联系方式,我如果有空会给大家解答的

  • 创建pom.xml
<?xml  version="1.0" encoding="UTF-8"?>"http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">4.0.0com.xiaoliuliusix-finger-webjar1.0-SNAPSHOTorg.projectlomboklombok1.18.12providedcglibcglib3.1io.nettynetty-all4.1.51.Final

HttpServer

Netty 编写 HTTP 服务器主类

package com.xiaoliuliu.six.finger.web.server;

import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;import io.netty.handler.logging.LogLevel;import io.netty.handler.logging.LoggingHandler;

import java.net.InetSocketAddress;

/** * @author 小六六 * @version 1.0 * @date 2020/10/13 11:41 * Netty 编写 HTTP 服务器 * 主类 */public class HttpServer {

    /**     * @Des 端口 http请求的端口     * @Author 小六六     * @Date 2020/10/13 11:42     * @Param     * @Return     */    int port;

    /**     * @Des 构造方法     * @Author 小六六     * @Date 2020/10/13 11:42     * @Param     * @Return     */    public HttpServer(int port) {        this.port = port;    }

    /**     * @Des 服务的启动方法     * @Author 小六六     * @Date 2020/10/13 11:43     * @Param     * @Return     */    public void start() throws Exception {        //启动引导类        ServerBootstrap bootstrap = new ServerBootstrap();        NioEventLoopGroup boss = new NioEventLoopGroup();        NioEventLoopGroup work = new NioEventLoopGroup();

        bootstrap.group(boss, work)                .handler(new LoggingHandler(LogLevel.DEBUG))                .channel(NioServerSocketChannel.class)                .childHandler(new HttpServerInitializer());

        ChannelFuture cf = bootstrap.bind(new InetSocketAddress(port)).sync();        System.out.println(" server start up on port : " + port);        cf.channel().closeFuture().sync();    }}

HttpServerInitializer

package com.xiaoliuliu.six.finger.web.server;

import io.netty.channel.ChannelHandler;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.http.HttpObjectAggregator;import io.netty.handler.codec.http.HttpServerCodec;

/** * @author 小六六 * @version 1.0 * @date 2020/10/13 11:57 * 用于配置 pipeline的处理链 */public class HttpServerInitializer extends ChannelInitializer {    @Override    protected void initChannel(SocketChannel socketChannel) throws Exception {        ChannelPipeline pipeline = socketChannel.pipeline();        // http 编解码        pipeline.addLast(new HttpServerCodec());        // http 消息聚合器        pipeline.addLast("httpAggregator",new HttpObjectAggregator(512*1024));        // 请求处理器        pipeline.addLast(new HttpRequestHandler());    }}

HttpRequestHandler

package com.xiaoliuliu.six.finger.web.server;

import io.netty.buffer.Unpooled;import io.netty.channel.ChannelFutureListener;import io.netty.channel.ChannelHandler;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.http.*;import io.netty.util.AsciiString;import io.netty.util.CharsetUtil;

import java.util.HashMap;import java.util.Map;

import static io.netty.handler.codec.http.HttpUtil.is100ContinueExpected;

/** * @author 小六六 * @version 1.0 * @date 2020/10/13 12:01 * 核心处理http请求的类,包括url的匹配核心方法都是在channelRead0方法 */public class HttpRequestHandler extends SimpleChannelInboundHandler {    private static final String FAVICON_ICO = "/favicon.ico";    private static final AsciiString CONNECTION = AsciiString.cached("Connection");    private static final AsciiString KEEP_ALIVE = AsciiString.cached("keep-alive");    @Override    public void channelReadComplete(ChannelHandlerContext ctx) {        ctx.flush();    }    @Override    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {        System.out.println("获得的参数:"+req);if (is100ContinueExpected(req)) {            ctx.write(new DefaultFullHttpResponse(                    HttpVersion.HTTP_1_1,                    HttpResponseStatus.CONTINUE));        }        // 获取请求的uri        String uri = req.uri();        Map resMap = new HashMap<>();        resMap.put("method",req.method().name());        resMap.put("uri",uri);        String msg = "小六六提醒你你请求uri为:" + uri+"";        // 创建http响应        DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,                HttpResponseStatus.OK,                Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));        //设置头信息        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");        //把消息输出到浏览器        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {        cause.printStackTrace();        ctx.close();    }}

ApplicationServer 测试类

package com.xiaoliuliu.six.finger.web.demo.server;

import com.xiaoliuliu.six.finger.web.server.HttpServer;

/** * @author 小六六 * @version 1.0 * @date 2020/10/13 14:26 *  这个类 用于 搭建Netty web服务器的测试类,只适用于搭建教程的第一篇文章 */public class ApplicationServer {    public static void main(String[] args) throws Exception {        HttpServer server = new HttpServer(8081);// 8081为启动端口        server.start();    }}

测试结果

在浏览器上输入

http://localhost:8081/xiaoliuliu

我们看看输出


然后我们来看看控制台


发现多了一次请求,这个是什么原因呢?

这是因为HttpRequestDecoder把请求拆分成HttpRequest和HttpContent两部分,

所以我们要过滤哪个/favicon.ico的请求,所以改改代码

    if("/favicon.ico".equals(uri)) {            System.out.println("请求了 favicon.ico, 不做响应");            return;        }

结尾

好了,今天我们用几十行代码实现了一个简单的Http服务器,很多的细节我们j就不一一讲解,但是我的注释基本上都写了,如果你有看不懂的地方,欢迎你来找我,我有空会给大家解答的,然后下一章就是我们要写的SpringMVC相关的代码了。


日常求赞

好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是真粉

创作不易,各位的支持和认可,就是我创作的最大动力,我们下篇文章

六脉神剑 | 文 【原创】如果本篇博客有任何错误,请批评指教,不胜感激 !

java web 显示项目下的图片_[适合初中级Java程序员修炼手册从0搭建整个Web项目](一)...相关推荐

  1. apache为什么更适合处理动态请求_[适合初中级Java程序员修炼手册从0搭建整个Web项目](一)...

    前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206种一棵树最好的时间是十年前,其次是现在 six-finger-web 一个Web后端 ...

  2. java web项目_[适合初中级Java程序员修炼手册从0搭建整个Web项目](二)

    前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206种一棵树最好的时间是十年前,其次是现在 six-finger-web 一个Web后端 ...

  3. 【读书笔记】程序员修炼手册—实战式学习最有效(项目驱动)

    持续学习&持续更新中- 学习态度:守破离 程序员修炼手册-实战式学习最有效(项目驱动) 1.学会观察这个世界(学会思考) 2.学会学习再去学习(守破离) 守 破 离 3.要动手,实战吧(JUS ...

  4. 20200928 006.简单错误如何处理_守破离学习法_程序员修炼手册

    学习思路:守 破 离 1.守 刚开始学习,首先要做到对老师和知识的"敬畏之心".学习就要先信服老师,不服老师就别学.你服谁,就去向谁学:不服,不如不去:谁都不服,那你已经天下第一, ...

  5. java开发有不加班的吗_千万不要相信程序员在加班时间写的代码!

    作为一个最底层的程序员,我先记录一些只有底层程序员才会知道的事情.如果多年后,我违背自己进入这个行业的初心,走上管理岗位,也能回想起一些禁忌,避免一些错误. 其中最重要的就是这条:不要相信一个程序员在 ...

  6. 006.尚学堂阶段1_简单错误如何处理_守破离学习法_程序员修炼手册

    程序员修理手册https://www.bjsxt.com/xiulian.html#1F

  7. Python学习_006.Python简单错误如何处理-守破离学习法_程序员修炼手册

    简单错误如何处理: 1.与老师对照 发现错误 2.百度等等搜索 3.最后请教老师或高手 守破离学习法: 守:按照老师要求的内容去学去练 破:发现问题解决问题 展开自己的思路 离:反复发现问题解决问题 ...

  8. 开发Java,市值一度超过两千亿美元,造福无数程序员的Sun公司,也最终“陨落”...

    "那些疯狂到认为自己能够改变世界的人,才是真正能够改变世界的人." 这是乔布斯曾说过的话,也是很多技术大佬都会坚守的信念.最突出的表现则在于他们性格方面足够的特立独行,甚至是有些偏 ...

  9. java程序员修炼之道

    今天在论坛里看到了一位工作10年的java大牛总结的java程序员修炼之道,看完后给出的评价是:字字玑珠,深入人心,猛回头,自己一无是处··· 大牛告诉我们应该好好学习与修炼以下知识与技能 Java语 ...

最新文章

  1. 再造人类生命的神奇细胞Human.Life.Our.Amazing.Cell
  2. Mysql Case when 语句
  3. 语音识别:时间序列Damerau–Levenshtein距离
  4. ADO.NET连接字符串
  5. 1203正规式转换为有穷自动机
  6. 多语言应用开发中本地化信息对照表
  7. 一招搞定css页面布局
  8. Spark-shell 脚本批量执行命令,命令行批量执行命令
  9. 温习下C语言一些函数
  10. mysql数据库创建带-的数据库名
  11. mysql编码丢了_记住:永远不要在 MySQL 中使用 UTF-8
  12. 系统关机函数ExitWindowsEx详解
  13. Linux入门的基础知识点
  14. servlet 跳转到 jsp 乱码解决
  15. 数据结构之——拓补排序和并查集
  16. Python 打怪兽游戏
  17. 不敢相信!那些真实存在的机器人女友们!
  18. 假设检验:p-value,FDR,q-value
  19. nginx部署vue项目(成功版)
  20. Python学习笔记32:Python线程_多线程的使用_线程执行带有参数的任务

热门文章

  1. 唠唠面试常问的:面向对象六大原则
  2. 【译】Spring Boot 2.0 官方迁移指南
  3. IT从业者进阶指南:如何提升自身的不可替代性
  4. 大数据文字游戏_基于大数据的游戏化教学系统研究.docx
  5. VSS介绍和备份技巧
  6. Transformer t2t vit
  7. No module named 'numpy.core._multiarray_umath'
  8. 一文看懂深度学习AutoML和NAS
  9. Invalid character escape '\o'.
  10. MnasNet 测试