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

前言

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

six-finger-web

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

github

为啥要写这个轮子

其实是这样的,小六六自己平时呢?有时候喜欢看看人家的源码比如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的第一篇,所以我尽量把点点滴滴做到

b935606476453ffe94365bbbf7fc4547.png

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

  • 创建pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="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"><modelVersion>4.0.0</modelVersion><groupId>com.xiaoliuliu</groupId><artifactId>six-finger-web</artifactId><packaging>jar</packaging><version>1.0-SNAPSHOT</version><dependencies><!-- 为了代码简洁引入lombok,不需要再写setter和getter(可以不引入)--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope></dependency><!--动态代理相关--><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.1</version></dependency><!-- Netty相关--><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.51.Final</version></dependency></dependencies>
</project>

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<SocketChannel> {@Overrideprotected 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<FullHttpRequest> {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");@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) {ctx.flush();}@Overrideprotected 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));}// 获取请求的uriString uri = req.uri();Map<String,String> resMap = new HashMap<>();resMap.put("method",req.method().name());resMap.put("uri",uri);String msg = "<html><head><title>小六六提醒你</title></head><body>你请求uri为:" + uri+"</body></html>";// 创建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);}@Overridepublic 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

我们看看输出

e96d13a51d74ef99736498ba1532efbf.png

然后我们来看看控制台

e279ef03a4ffe04c8e65396861aff71d.png

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

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

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

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

结尾

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

9c604411fb9adec80f745e807032dc73.png

日常求赞

好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是真粉
创作不易,各位的支持和认可,就是我创作的最大动力,我们下篇文章
六脉神剑 | 文 【原创】如果本篇博客有任何错误,请批评指教,不胜感激 !

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/381566.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python如何自动缩进_Python缩进

缩进出现问题&#xff0c;运行不出来。 正确代码如下&#xff1a;1 defbinary_search(list, item):2 low 03 high len(list)-1 4 5 while low <high:6 mid (low high)7 guess list[mid]8 if guess item:9 returnmid10 if guess >item:11 high mid-1 12 else:13 low m…

差分约束系统详解

一直不知道差分约束是什么类型题目&#xff0c;最近在写最短路问题就顺带看了下&#xff0c;原来就是给出一些形如x-y<b不等式的约束&#xff0c;问你是否满足有解的问题 好神奇的是这类问题竟然可以转换成图论里的最短路径问题&#xff0c;下面开始详细介绍下 比如给出三…

美开发思想头盔让士兵通过脑电波交流

http://www.sina.com.cn 2008年09月18日 08:08 新浪科技新浪科技讯 北京时间9月18日消息&#xff0c;据美国《时代》周刊报道&#xff0c;在20世纪的战场上&#xff0c;爆炸声震耳欲聋&#xff0c;军官们要下达命令&#xff0c;或者士兵之间互相交流看法&#xff0c;只能大声…

flink source 同步_大数据面试题-Flink

1、Flink 的 抽象层次有几种Stateful stream processingCore APITableSQL 2、Window 类型(1)TimeWindowTumbling Window(滚动窗口)Sliding Window(滑动窗口)Session Window(会话窗口)Global Window(全局窗口)(2)countWindow(3)自定义window 3、Time 类型事件时间、注入时间和Pr…

python 程序员专属情话_程序员高端情话来一波,你想要的情话原来都在这里......

原标题&#xff1a;程序员高端情话来一波&#xff0c;你想要的情话原来都在这里...程序员最幽默(ID&#xff1a;humor1024)整编图片来自&#xff1a;网络今天是2019年8月7号&#xff0c;一年一度的情人节又来了作为屌丝界的一枚程序员怎么能不参与到这个振奋人心的日子里呢&…

HDU ACM Steps攻略 ACM Steps的全部内容

原地址&#xff1a;http://www.byywee.com/page/M0/S607/607452.html 总结了一下ACM STEPS的各章内容&#xff0c;趁便附上我的Steps题号&#xff08;每人的不一样&#xff09;。 别的&#xff0c;此文首要目标是为了装逼&#xff1b; 大牛请疏忽&#xff1b; 摸索欲斗劲强…

ASP.NET中常用的js代码

ASP.NET中常用的js代码 所属类别&#xff1a;ASP.net推荐指数&#xff1a;★★☆文档人气&#xff1a;61本周人气&#xff1a;3发布日期&#xff1a;2008-7-8三、弹出框1、 弹出提示框Alert("提示框&#xff0c;呵呵");2、 弹出确认框return confirm("确认框&am…

linux孟庆昌第六章课后题_第六章课后练习题答案

第四部分课后练习题一、单项选择题1&#xff0e;某投资方案的年营业收入为元&#xff0c;年总营业成本为60000元&#xff0c;其中年折旧额10000元&#xff0c;所得税率为33&#xff05;&#xff0c;该方案的每年营业现金流量为( B)。A&#xff0e;26800元B&#xff0e;36800元C…

1.1.1.1校园网_Apache Flink 1.11.0 重要功能全面解析

来源 | Apache Flink 官方博客翻译 | 高赟(云骞)Apache Flink 社区很荣幸的宣布 Flink 1.11.0 版本正式发布&#xff01;超过 200 名贡献者参与了 Flink 1.11.0 的开发&#xff0c;提交了超过 1300 个修复或优化。这些修改极大的提高了 Flink 的可用性&#xff0c;并且增强了各…

双硬盘双win10互不干扰_笔者详解win10系统双硬盘经常提示“盘符交错”的技巧...

你是否遇到过win10系统双硬盘经常提示“盘符交错”的问题。那么出现win10系统双硬盘经常提示“盘符交错”的问题该怎么解决呢&#xff1f;很多对电脑不太熟悉的小伙伴不知道win10系统双硬盘经常提示“盘符交错”到底该如何解决&#xff1f;其实只需要  一、修复windows  二、…

[leetcode] 617. Merge Two Binary Trees

题目描述 给定两棵树&#xff0c;要求合并它们&#xff0c;如果节点重合则新合并的树的节点为它们之和&#xff0c;否则不变。 思路 简单递归&#xff0c;c语言怎么创建新节点忘记了&#xff0c;就直接写的。 代码 /*** Definition for a binary tree node.* struct TreeNode {…

python定时任务_Python定时任务(上)

在项目中&#xff0c;我们可能遇到有定时任务的需求。其一&#xff1a;定时执行任务。例如每天早上 8 点定时推送早报。其二&#xff1a;每隔一个时间段就执行任务。比如&#xff1a;每隔一个小时提醒自己起来走动走动&#xff0c;避免长时间坐着。今天&#xff0c;我跟大家分享…

3-font

第三章 font-family控制文字字体font-family:Arial, Helvetica, sans-serif;依次采用列表中的字体&#xff0c;如果没有系统中没有安装&#xff0c;则采用浏览器默认字体。font-size控制文字大小1in&#xff08;英寸&#xff09; 2.54cm&#xff08;厘米&#xff09; 25.4 mm…

显示控制器注释_欧姆龙可编程控制器CS1D-CPU产品型号说明及功能介绍

欧姆龙可编程控制器CS1D-CPU用CPU单元 CPU单元(用于双CPU系统)欧姆龙可编程控制器CS1D-CPU用CPU单元 特点可以轻松引入、使用高可靠性系统成双配备CPU单元轻松易行CPU单元内的程序或内部数据在活动/备用CPU之间完全进行自动传送并进行同步。 无需选择要同步的数据或单独进行传送…

oracle查看数据库是否恢复成功_记一次解决docker下oracle数据库故障事例

一、问题背景&#xff1a;某个项目的线上环境oracle数据库挂了&#xff0c;同事急匆匆来找我救火。我简单咨询了一些基本情况&#xff1a;线上环境&#xff0c;docker部署&#xff0c;已正常运行半年。由于宿主机的根目录硬盘空间不够&#xff0c;运维的同事想把oracle数据文件…

[调剂复试]复试后的一点总结

来北京差不多有两天了&#xff0c;调剂的事情也有了结果&#xff0c;之前的忐忑的心也终于放了下来。好不容易有一点空闲的时间&#xff0c;所以想好好地总结一下&#xff0c;谈不上有多少经验&#xff0c;只是希望阅读这篇文章的人能够在迷茫的时候看到方向。 先说下调剂的学…

js取字符串后四位_JS逆向 | 某验滑块加密参数逆向分析

声明&#xff1a;本文只作学习研究&#xff0c;禁止用于非法用途&#xff0c;否则后果自负&#xff0c;如有侵权&#xff0c;请告知删除&#xff0c;谢谢&#xff01;aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vZGVtby9zbGlkZS1mbG9hdC5odG1s抓包分析&#xff0c;看到一个加密参数w&…

谨防代理木马和怕米释放有毒程序

江民今日提醒您注意&#xff1a;在今天的病毒中Trojan/PSW.Agent.ann“代理木马”变种ann和TrojanDropper.Psyme.gke“怕米”变种gke值得关注。 英文名称&#xff1a;Trojan/PSW.Agent.ann中文名称&#xff1a;“代理木马”变种ann病毒长度&#xff1a;243200字节病毒类型&…

[python] 命令行模式下出现cp65001异常

问题 在命令行模式下有时会提示cp65001异常&#xff0c;很显然是命令行编码和python环境编码不匹配。 解决 切换命令行编码 unknown encoding: cp65001异常 python安装后进入命令行交互模式&#xff0c;输入任何代码都报unknown encoding: cp65001异常 需要将编码(UTF-8)修改…

挖掘城市ip_德国卡尔斯草莓农庄:旅游IP打造要创意更要形象!

什么是IP?名人圈&#xff1a;杨超越游戏圈&#xff1a;王者荣耀影视界&#xff1a;延禧攻略出版界&#xff1a;Harry Potter相声界&#xff1a;郭德纲……别忙着争先恐后&#xff0c;知道你的IP数不胜数~~你知道的IP数不胜数&#xff0c;一个人、一部作品、一个品牌、一座城市…