netty 實(shí)現(xiàn)tomcat的示例代碼
netty 實(shí)現(xiàn)tomcat
自定義基礎(chǔ)類
TomcatServlet
public abstract class TomcatServlet { public void service(ServletRequest request, ServletResponse response){ if ("GET".equalsIgnoreCase(request.getMethod())){ doGet(request, response); }else if ("POST".equalsIgnoreCase(request.getMethod())){ doPost(request, response); }else { doResponse(response, "暫不支持其它請(qǐng)求方法"); } } public abstract void doGet(ServletRequest request, ServletResponse response); public abstract void doPost(ServletRequest request, ServletResponse response); public void doResponse(ServletResponse response, String message){ response.write(message); } }
ServletRequest
@Data public class ServletRequest { private ChannelHandlerContext context; private HttpRequest httpRequest; public ServletRequest(){ } public ServletRequest(ChannelHandlerContext context, HttpRequest httpRequest){ this.context = context; this.httpRequest = httpRequest; } public String getMethod(){ return httpRequest.method().name(); } public HttpHeaders getHeaders(){ return httpRequest.headers(); } public Map<String, List<String>> getParameters(){ QueryStringDecoder decoder = new QueryStringDecoder(httpRequest.uri()); return decoder.parameters(); } public Map<String,String> getPostFormParameters(){ Map<String,String> params = new HashMap<>(); HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(httpRequest); decoder.getBodyHttpDatas().forEach(item -> { if (item.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute){ Attribute attribute = (Attribute) item; try { String key = attribute.getName(); String value = attribute.getValue(); params.put(key, value); }catch (Exception e){ e.printStackTrace(); } } }); return params; } public Map<String, Object> getPostBody(){ ByteBuf content = ((FullHttpRequest)httpRequest).content(); byte[] bytes = new byte[content.readableBytes()]; content.readBytes(bytes); return JSON.parseObject(new String(bytes)).getInnerMap(); } }
ServletResponse
@Data public class ServletResponse { private ChannelHandlerContext context; private HttpRequest httpRequest; public ServletResponse(){ } public ServletResponse(ChannelHandlerContext context, HttpRequest httpRequest){ this.context = context; this.httpRequest = httpRequest; } public void write(String message){ FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); response.headers().set("Content-Type","application/json;charset=utf-8"); response.content().writeCharSequence(message, StandardCharsets.UTF_8); context.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } }
CustomServlet
ublic class CustomServlet extends TomcatServlet{ @Override public void doGet(ServletRequest request, ServletResponse response) { System.out.println("處理GET請(qǐng)求"); System.out.println("請(qǐng)求參數(shù)為:"); request.getParameters().forEach((key,value) -> System.out.println(key + " ==> "+value)); doResponse(response, "GET success"); } @Override public void doPost(ServletRequest request, ServletResponse response) { if (request.getHeaders().get("Content-Type").contains("x-www-form-urlencoded")){ System.out.println("處理POST Form請(qǐng)求"); System.out.println("請(qǐng)求參數(shù)為:"); request.getPostFormParameters().forEach((key,value) -> System.out.println(key + " ==> " + value)); doResponse(response, "POST Form success"); }else if (request.getHeaders().get("Content-Type").contains("application/json")){ System.out.println("處理POST json請(qǐng)求"); System.out.println("請(qǐng)求參數(shù)為:"); request.getPostBody().forEach((key,value) -> System.out.println(key + " ==> " + value)); doResponse(response, "POST json success"); }else { doResponse(response, "error:暫不支持其它post請(qǐng)求方式"); } } }
ServletMapping:url與對(duì)應(yīng)的TomcatServlet映射
public class ServletMapping { private static final Map<String,TomcatServlet> urlServletMapping = new HashMap<>(); public static Map<String, TomcatServlet> getUrlServletMapping(){ return urlServletMapping; } }
web.properties:使用properties存儲(chǔ)url與對(duì)應(yīng)的TomcatServet
servlet.url=/hello servlet.className=com.example.demo.tomcat.servlet.CustomServlet
netty 服務(wù)端
CustomServerHandler
public class CustomServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> { @Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest request) throws Exception { String uri = request.uri(); String path = uri; if (uri.contains("?")){ path = uri.substring(0,uri.indexOf("?")); } if (ServletMapping.getUrlServletMapping().containsKey(path)){ ServletRequest servletRequest = new ServletRequest(channelHandlerContext, request); ServletResponse servletResponse = new ServletResponse(channelHandlerContext, request); ServletMapping.getUrlServletMapping().get(path).service(servletRequest, servletResponse); }else { FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); response.content().writeCharSequence("404 NOT FOUND:"+path+"不存在", StandardCharsets.UTF_8); channelHandlerContext.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } } }
NettyServer
public class NettyServer { private static final Properties webProperties = new Properties(); public static void init(){ try { InputStream inputStream = new FileInputStream("./web.properties"); webProperties.load(inputStream); for (Object item : webProperties.keySet()){ String key = (String)item; if (key.endsWith(".url")){ String servletKey = key.replaceAll("\\.url","\\.className"); String servletName = webProperties.getProperty(servletKey); TomcatServlet servlet = (TomcatServlet) Class.forName(servletName).newInstance(); ServletMapping.getUrlServletMapping().put(webProperties.getProperty(key),servlet); } } }catch (Exception e){ e.printStackTrace(); } } public static void startServer(int port){ init(); EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true) .childHandler(new ChannelInitializer<SocketChannel>() { @Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline channelPipeline = socketChannel.pipeline(); channelPipeline.addLast(new HttpRequestDecoder()); channelPipeline.addLast(new HttpResponseEncoder()); channelPipeline.addLast(new HttpObjectAggregator(65535)); channelPipeline.addLast(new CustomServerHandler());} }); ChannelFuture channelFuture = serverBootstrap.bind(port).sync(); channelFuture.channel().closeFuture().sync(); }catch (Exception e){ e.printStackTrace(); }finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) { startServer(8000); } }
使用測(cè)試
get請(qǐng)求:localhost:8000/hello?name=瓜田李下&age=20
處理GET請(qǐng)求
請(qǐng)求參數(shù)為:
name ==> [瓜田李下]
age ==> [20]
get請(qǐng)求:localhost:8000/hello2?name=瓜田李下&age=20
/hello2路徑?jīng)]有對(duì)應(yīng)的TomcatServlet處理
Post form請(qǐng)求:x-www-form-urlencoded
處理POST Form請(qǐng)求
請(qǐng)求參數(shù)為:
name ==> 瓜田李下
age ==> 20
Post json請(qǐng)求
處理POST json請(qǐng)求
請(qǐng)求參數(shù)為:
name ==> 瓜田李下
age ==> 20
Post form-data請(qǐng)求
目前只支持x-www-form-urlencoded、post json請(qǐng)求,不支持其它請(qǐng)求方式
Put:localhost:8000/hello?name=瓜田李下&age=20
目前只支持GET、POST請(qǐng)求方法,不支持其它方法
到此這篇關(guān)于netty 實(shí)現(xiàn)tomcat的文章就介紹到這了,更多相關(guān)netty 實(shí)現(xiàn)tomcat內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。