servlet.one.url=/firstServlet.do
servlet.one.className=com.rt.netty.tomcat.servlet.FirstServlet
servlet.two.url=/secondServlet.do
servlet.two.className=com.rt.netty.tomcat.servlet.SecondServlet
private Map servletMapping = new HashMap();
private Properties webxml = new Properties();
private void init(){
//加载web.xml文件,同时初始化 ServletMapping对象
try{
String WEB_INF = this.getClass().getResource("/").getPath();
FileInputStream fis = new FileInputStream(WEB_INF + "web.properties");
webxml.load(fis);
for (Object k : webxml.keySet()) {
String key = k.toString();
if(key.endsWith(".url")){
String servletName = key.replaceAll("\.url$", "");
String url = webxml.getProperty(key);
String className = webxml.getProperty(servletName + ".className");
RTServlet obj = (RTServlet)Class.forName(className).newInstance();
servletMapping.put(url, obj);
}
}
}catch(Exception e){
e.printStackTrace();
}
}
//Netty封装了NIO,Reactor模型,Boss,worker
// Boss线程
EventLoopGroup bossGroup = new NioEventLoopGroup();
// Worker线程
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
// Netty服务
//ServetBootstrap ServerSocketChannel
ServerBootstrap server = new ServerBootstrap();
// 链路式编程
server.group(bossGroup, workerGroup)
// 主线程处理类,看到这样的写法,底层就是用反射
.channel(NioServerSocketChannel.class)
// 子线程处理类 , Handler
.childHandler(new ChannelInitializer() {
// 客户端初始化处理
protected void initChannel(SocketChannel client) throws Exception {
// 无锁化串行编程
//Netty对HTTP协议的封装,顺序有要求
// HttpResponseEncoder 编码器
client.pipeline().addLast(new HttpResponseEncoder());
// HttpRequestDecoder 解码器
client.pipeline().addLast(new HttpRequestDecoder());
// 业务逻辑处理
client.pipeline().addLast(new RTTomcatHandler());
}
})
// 针对主线程的配置 分配线程最大数量 128
.option(ChannelOption.SO_BACKLOG, 128)
// 针对子线程的配置 保持长连接
.childOption(ChannelOption.SO_KEEPALIVE, true);
// 启动服务器
ChannelFuture f = server.bind(port).sync();
System.out.println("Tomcat 已启动,监听的端口是:" + port);
f.channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}finally {
// 关闭线程池
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
public class RTTomcatHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof HttpRequest){
HttpRequest req = (HttpRequest) msg;
// 转交给我们自己的request实现
RTRequest request = new RTRequest(ctx,req);
// 转交给我们自己的response实现
RTResponse response = new RTResponse(ctx,req);
// 实际业务处理
String url = request.getUrl();
if(servletMapping.containsKey(url)){
servletMapping.get(url).service(request, response);
}else{
response.write("404 - Not Found");
}
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
}
}
private ChannelHandlerContext ctx;
private HttpRequest req;
public RTRequest(ChannelHandlerContext ctx, HttpRequest r
this.ctx = ctx;
this.req = req;
}
public String getUrl() {
return req.uri();
}
public String getMethod() {
return req.method().name();
}
public class RTResponse {
//SocketChannel的封装
private ChannelHandlerContext ctx;
private HttpRequest req;
public RTResponse(ChannelHandlerContext ctx, HttpRequest req) {
this.ctx = ctx;
this.req = req;
}
public void write(String out) throws Exception {
try {
if (out == null || out.length() == 0) {
return;
}
// 设置 http协议及请求头信息
FullHttpResponse response = new DefaultFullHttpResponse(
// 设置http版本为1.1
HttpVersion.HTTP_1_1,
// 设置响应状态码
HttpResponseStatus.OK,
// 将输出值写出 编码为UTF-8
Unpooled.wrappedBuffer(out.getBytes("UTF-8")));
response.headers().set("Content-Type", "text/html;");
// 当前是否支持长连接
// if (HttpUtil.isKeepAlive(r)) {
// // 设置连接内容为长连接
// response.headers().set(CONNECTION, HttpHeaderValues.KEEP_ALIVE);
// }
ctx.write(response);
} finally {
ctx.flush();
ctx.close();
}
}
}
public abstract class RTServlet {
public void service(RTRequest request, RTResponse response) throws Exception{
//由service方法来决定,是调用doGet或者调用doPost
if("GET".equalsIgnoreCase(request.getMethod())){
doGet(request, response);
}else{
doPost(request, response);
}
}
public abstract void doGet(RTRequest request, RTResponse response) throws Exception;
public abstract void doPost(RTRequest request, RTResponse response) throws Exception;
}
public void doGet(RTRequest request, RTResponse response) throws Exception {
this.doPost(request, response);
}
public void doPost(RTRequest request, RTResponse response) throws Exception {
response.write("This is rt First Serlvet");
}
}
public class SecondServlet extends RTServlet {
public void doGet(RTRequest request, RTResponse response) throws Exception {
this.doPost(request, response);
}
public void doPost(RTRequest request, RTResponse response) throws Exception {
response.write("This is rt Second Serlvet");
}
}