使用netty实现一个http挡板,轻量又实用。收藏起来吧
生活随笔
收集整理的這篇文章主要介紹了
使用netty实现一个http挡板,轻量又实用。收藏起来吧
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
一、需要的包
?二、代碼
三、導出jar包
四、啟動jar包
五、使用
一、需要的包
?二、代碼
package com.cxf.http;import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.handler.stream.ChunkedWriteHandler;public class NettyHttpServer{private int inetPort;public NettyHttpServer(int inetPort) {this.inetPort = inetPort;}public int getInetPort() {return inetPort;}public void init() throws Exception {EventLoopGroup parentGroup = new NioEventLoopGroup();EventLoopGroup childGroup = new NioEventLoopGroup();try {ServerBootstrap server = new ServerBootstrap();// 1. 綁定兩個線程組分別用來處理客戶端通道的accept和讀寫時間server.group(parentGroup, childGroup)// 2. 綁定服務端通道NioServerSocketChannel.channel(NioServerSocketChannel.class)// 3. 給讀寫事件的線程通道綁定handler去真正處理讀寫// ChannelInitializer初始化通道SocketChannel.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {// 請求解碼器socketChannel.pipeline().addLast("http-decoder", new HttpRequestDecoder());// 將HTTP消息的多個部分合成一條完整的HTTP消息socketChannel.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65535));// 響應轉碼器socketChannel.pipeline().addLast("http-encoder", new HttpResponseEncoder());// 解決大碼流的問題,ChunkedWriteHandler:向客戶端發送HTML5文件socketChannel.pipeline().addLast("http-chunked", new ChunkedWriteHandler());// 自定義處理handlersocketChannel.pipeline().addLast("http-server", new NettyHttpServerHandler());}});System.out.println("Netty-http服務器已啟動,端口" + inetPort);// 4. 監聽端口(服務器host和port端口),同步返回// ChannelFuture future = server.bind(inetHost, this.inetPort).sync();ChannelFuture future = server.bind(this.inetPort).sync();// 當通道關閉時繼續向后執行,這是一個阻塞方法future.channel().closeFuture().sync();} finally {childGroup.shutdownGracefully();parentGroup.shutdownGracefully();}}public static void main(String[] args) {NettyHttpServer nettyHttpServer = new NettyHttpServer(Integer.parseInt(args[0]));try {nettyHttpServer.init();} catch (Exception e) {e.printStackTrace();}}} package com.cxf.http;import static io.netty.buffer.Unpooled.copiedBuffer;import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.List; import java.util.Map;import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.DefaultFullHttpResponse; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.QueryStringDecoder; import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory; import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder; import io.netty.handler.codec.http.multipart.InterfaceHttpData; import io.netty.handler.codec.http.multipart.MemoryAttribute; import io.netty.util.CharsetUtil;/* * 自定義處理的handler */ public class NettyHttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {/** 處理請求*/@Overrideprotected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) throws IOException {FullHttpResponse response = null;if (fullHttpRequest.method() == HttpMethod.GET) {String data = getResponse(channelHandlerContext, fullHttpRequest);ByteBuf buf = copiedBuffer(data, CharsetUtil.UTF_8);response = responseOK(HttpResponseStatus.OK, buf);} else if (fullHttpRequest.method() == HttpMethod.POST) {String data = getResponse(channelHandlerContext, fullHttpRequest);ByteBuf content = copiedBuffer(data, CharsetUtil.UTF_8);response = responseOK(HttpResponseStatus.OK, content);} else {String data = "未找到對應的url";ByteBuf content = copiedBuffer(data, CharsetUtil.UTF_8);response = responseOK(HttpResponseStatus.INTERNAL_SERVER_ERROR, content);}// 發送響應channelHandlerContext.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);}private String getResponse(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) throws IOException {System.out.println("===============================");String uri = fullHttpRequest.getUri();System.out.println("請求url:" + uri);String content = fullHttpRequest.content().toString(CharsetUtil.UTF_8);System.out.println("請求內容:" + content);String path = new File(".").getCanonicalPath() + "/files" + uri;System.out.println("讀取擋板文件路徑:" + path);String data = getFileContent(path);System.out.println("返回內容:" + data);System.out.println("===============================");return data; } /*** @param fullHttpRequest* @return 獲取參數*/private String getParam(FullHttpRequest fullHttpRequest) {ByteBuf content = fullHttpRequest.content();byte[] reqContent = new byte[content.readableBytes()];content.readBytes(reqContent);String strContent = "";try {strContent = new String(reqContent, "UTF-8");} catch (UnsupportedEncodingException e) {// TODO 自動生成的 catch 塊e.printStackTrace();}return strContent;}/** 獲取GET方式傳遞的參數*/private Map<String, Object> getGetParamsFromChannel(FullHttpRequest fullHttpRequest) {Map<String, Object> params = new HashMap<String, Object>();//if (fullHttpRequest.method() == HttpMethod.GET) {// 處理get請求QueryStringDecoder decoder = new QueryStringDecoder(fullHttpRequest.uri());Map<String, List<String>> paramList = decoder.parameters();for (Map.Entry<String, List<String>> entry : paramList.entrySet()) {params.put(entry.getKey(), entry.getValue().get(0));}return params;//} else {// return null;//}}/** 獲取POST方式傳遞的參數*/private Map<String, Object> getPostParamsFromChannel(FullHttpRequest fullHttpRequest) {Map<String, Object> params = new HashMap<String, Object>();if (fullHttpRequest.method() == HttpMethod.POST) {// 處理POST請求String strContentType = fullHttpRequest.headers().get("Content-Type").trim();if (strContentType.contains("x-www-form-urlencoded")) {params = getFormParams(fullHttpRequest);} else if (strContentType.contains("application/json")) {try {params = getJSONParams(fullHttpRequest);} catch (UnsupportedEncodingException e) {return null;}} else {return null;}return params;} else {return null;}}/** 解析from表單數據(Content-Type = x-www-form-urlencoded)*/private Map<String, Object> getFormParams(FullHttpRequest fullHttpRequest) {Map<String, Object> params = new HashMap<String, Object>();HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), fullHttpRequest);List<InterfaceHttpData> postData = decoder.getBodyHttpDatas();for (InterfaceHttpData data : postData) {if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {MemoryAttribute attribute = (MemoryAttribute) data;params.put(attribute.getName(), attribute.getValue());}}return params;}/** 解析json數據(Content-Type = application/json)*/private Map<String, Object> getJSONParams(FullHttpRequest fullHttpRequest) throws UnsupportedEncodingException {Map<String, Object> params = new HashMap<String, Object>();ByteBuf content = fullHttpRequest.content();byte[] reqContent = new byte[content.readableBytes()];content.readBytes(reqContent);String strContent = new String(reqContent, "UTF-8");/* JSONObject jsonParams = JSONObject.fromObject(strContent);for (Object key : jsonParams.keySet()) {params.put(key.toString(), jsonParams.get(key));}*/return params;}private FullHttpResponse responseOK(HttpResponseStatus status, ByteBuf content) {FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, content);if (content != null) {response.headers().set("Content-Type", "text/json;charset=UTF-8");response.headers().set("Content_Length", response.content().readableBytes());}return response;}/*** 讀取文件的內容* 讀取指定文件的內容* @param path 為要讀取文件的絕對路徑* @return 以行讀取文件后的內容。* @since 1.0*/public static final String getFileContent(String path) throws IOException{String filecontent = "";try {File f = new File(path);if (f.exists()) {FileReader fr = new FileReader(path);BufferedReader br = new BufferedReader(fr); //建立BufferedReader對象,并實例化為brString line = br.readLine(); //從文件讀取一行字符串//判斷讀取到的字符串是否不為空while (line != null) {filecontent += line + "\n";line = br.readLine(); //從文件中繼續讀取一行數據}br.close(); //關閉BufferedReader對象fr.close(); //關閉文件}}catch (IOException e) {throw e;}return filecontent;}}三、導出jar包
詳細百度
四、啟動jar包
五、使用
1、在jar包同級目錄下創建files目錄。
2、在files目錄下新建test文件。
3、test文件中內容:
{"name":"zhangsan"}
4、使用postman發送測試一下吧。
?5、url與文件對應規則
localhost:8083/test?后面的test就是files目錄下對應的文件,文件內容會作為返回內容進行返回。
總結
以上是生活随笔為你收集整理的使用netty实现一个http挡板,轻量又实用。收藏起来吧的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java类的完整生命周期详解
- 下一篇: spring系列-注解驱动原理及源码-b