运行效果图:
servlet url配置信息保存在application.properties中,通过解析得到对应的url与方法的映射,并保存到内存中去,基于netty实现访问:代码如下
public void init() throws FileNotFoundException { String basePath = this.getClass().getResource("/").getPath() ; FileInputStream ins = new FileInputStream(new File(basePath + “application.properties”)) ; try { prop.load(ins); for (Object obj : prop.keySet()){ String key = trimToEmpty(obj) ; String property = prop.getProperty(key); if (key.endsWith(".port")){ if (!(property == “” || property == null)){ this.port = Integer.parseInt(property) ; } } if (key.endsWith(".url")) { Class clazz = Class.forName(prop.getProperty(key.replaceAll("\.url$",".className"))) ; Constructor constructor = clazz.getDeclaredConstructor(); if (!constructor.isAccessible()){ constructor.setAccessible(true); } urlMapping.put(property,(EasyServlet) constructor.newInstance()) ; } }
if (this.port <= 0){
this.port = 8080 ;
}
} catch (Exception e) {
e.printStackTrace();
}
} 处理器类:
public class EasyTomcatHandler extends ChannelInboundHandlerAdapter {
private Map<String,EasyServlet> urlMapping ;
public EasyTomcatHandler(Map<String, EasyServlet> mapping){
this.urlMapping = mapping ;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof HttpRequest){
HttpRequest req = (HttpRequest) msg;
EasyRequest request = new EasyRequest(ctx,req) ;
EasyResponse response = new EasyResponse(ctx,req) ;
String url = request.getUrl();
if (urlMapping.containsKey(url)){
EasyServlet servlet = urlMapping.get(url) ;
servlet.service(request,response);
}
}
}
} 当接收到请求的时候队请求进行处理
netty服务端代码:
**
-
@Author: drainli **/ public class EasyApplication { private int port ; Map<String, EasyServlet> urlMapping = new HashMap<>() ; Properties prop = new Properties() ; public static void main(String[] args) throws InterruptedException { new EasyApplication().startUp(); } public void startUp() throws InterruptedException { try {
init();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
ServerBootstrap bootstrap = new ServerBootstrap() ;
EventLoopGroup boss = new NioEventLoopGroup() ;
EventLoopGroup works = new NioEventLoopGroup() ;
bootstrap.group(boss,works)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new HttpResponseEncoder())
.addLast(new HttpRequestDecoder())
.addLast(new EasyTomcatHandler(urlMapping)) ;
}
})
.option(ChannelOption.SO_BACKLOG,128)
.childOption(ChannelOption.SO_KEEPALIVE,true) ;
ChannelFuture sync = bootstrap.bind(port).sync();
System.out.printf("server has startup,the listening port is :%d%n",port);
sync.channel().closeFuture().sync() ;
boss.shutdownGracefully() ;
works.shutdownGracefully() ;
} public void init() throws FileNotFoundException { String basePath = this.getClass().getResource("/").getPath() ; FileInputStream ins = new FileInputStream(new File(basePath + “application.properties”)) ; try { prop.load(ins); for (Object obj : prop.keySet()){ String key = trimToEmpty(obj) ; String property = prop.getProperty(key); if (key.endsWith(".port")){ if (!(property == “” || property == null)){ this.port = Integer.parseInt(property) ; } } if (key.endsWith(".url")) { Class clazz = Class.forName(prop.getProperty(key.replaceAll("\.url$",".className"))) ; Constructor constructor = clazz.getDeclaredConstructor(); if (!constructor.isAccessible()){ constructor.setAccessible(true); } urlMapping.put(property,(EasyServlet) constructor.newInstance()) ; } } if (this.port <= 0){
this.port = 8080 ;
}
} catch (Exception e) {
e.printStackTrace();
}
} private String trimToEmpty(Object obj){ return obj == null ? “” : String.valueOf(obj).trim() ; } } 访问 firstservlet.do接口时的效果图:
完整代码地址: https://gitee.com/drainli/easy-tomcat
|