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的第一篇,所以我盡量把點點滴滴做到
首先創建一個maven項目,如果這個都不會的話,小六六建議先學習基礎再來,在文章很多的地方,一些基礎的小六六是默認你懂,如果有啥不懂的可以上github上找我聯系方式,我如果有空會給大家解答的
- 創建pom.xml
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我們看看輸出
然后我們來看看控制臺
發現多了一次請求,這個是什么原因呢?
這是因為HttpRequestDecoder把請求拆分成HttpRequest和HttpContent兩部分,
所以我們要過濾哪個/favicon.ico的請求,所以改改代碼
if("/favicon.ico".equals(uri)) {System.out.println("請求了 favicon.ico, 不做響應");return;}結尾
好了,今天我們用幾十行代碼實現了一個簡單的Http服務器,很多的細節我們一一講解,但是我的注釋基本上都寫了,如果你有看不懂的地方,歡迎你來找我,我有空會給大家解答的,然后下一章就是我們要寫的SpringMVC相關的代碼了。
日常求贊
好了各位,以上就是這篇文章的全部內容了,能看到這里的人呀,都是真粉。創作不易,各位的支持和認可,就是我創作的最大動力,我們下篇文章
六脈神劍 | 文 【原創】如果本篇博客有任何錯誤,請批評指教,不勝感激 !
總結
以上是生活随笔為你收集整理的apache为什么更适合处理动态请求_[适合初中级Java程序员修炼手册从0搭建整个Web项目](一)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不得不爱第2季剧情介绍
- 下一篇: linux孟庆昌第六章课后题_第六章课后