徒手用Java来写个Web服务器和框架吧<第一章:NIO篇>

徒手用Java来写个Web服务器和框架吧<第二章:Request和Response>

这一章先把Web框架的功能说一些,有个雏形。

先是制作一个Service,并绑定到一个正则地址。用到了注解和反射。

项目地址: Telemarketer

2017年08月02日更新 已改成注解模式注册 等有空更新


Service的定义

Telemarketer的Service是一个服务。请求了跟它关联的地址,那就由它来为你服务。

它对外只需一个方法。并且对这个方法的要求大概只有输入一个Request,可以返回一个Response这么简单。

那就这样

public interface Service {
Response execute(Request request);
}

问题来了,如何把它关联到uri上呢?第一想法是在创建一个注册中心。

Service的绑定

这部分代码在这里,可参考查看

先来手动挡

新建一个类ServiceRegistry, 在里面放这么一个静态的Map:

private static Map<String, Service> services = new TreeMap<>();

还提供了这么一个方法:

public static void register(String pattern, Service service) {services.put(pattern, service);}

然后再提供查找服务的方法。

public static Service findService(String pattern) {
for (Map.Entry<String, Service> entry : services.entrySet()) {
if (pattern.matches(entry.getKey())) {
return entry.getValue();
}
}
return null;
}
这样不就根据request确定了服务对象吗?让人们自己动手丰衣足食吧。

然而转念一想,这么搞多麻烦,还得让人专门找个地方register一大堆?这一点都不方便..懒惰是第一大生产力!

那再换个自动挡。

再来自动挡

稍微一想Spring那些框架,用注解搞依赖注入用的那是飞起,Telemarketer也可以!来,说干就干!

先确定注解三个要点

    1. 确定目标:类
    2. 确定范围:运行时
    3. 确定内容:一个String可以放地址正则就好
 @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface InService {
String urlPattern();
}

有了这个,赶紧写个服务先标上。地址正则就匹配根目录吧

 @InService(urlPattern = "^/$")
public class IndexService implements Service {
@Override
public Response execute(Request request) {
return new FileResponse(Status.SUCCESS_200, PropertiesHelper.getTemplateFile("index.html"));
}
}

PropertiesHelper.getTemplateFile("index.html")  返回的是一个html的文件,暂时不用管。FileResponse是包含文件内容的Response。

行了,现在想想怎么靠这个注解自动注册呢?

假设我们知道了这个类名是 edu.telemarketer.services.servicesimpls.IndexService 。先反射一个:

Class<?> aClass = Class.forName("edu.telemarketer.services.servicesimpls.IndexService");

注意这里用Class.forName()和ClassLoader的load()方法区别:Class.forName()会初始化类中的静态域,有什么static都会准备好,而ClassLoader的load就不会有这样的效果。

弄到这个Class对象后,获取InService标注

InService annotation = aClass.getAnnotation(InService.class);

判断一下是不是null 再判断一下Service.class是不是这个类的接口。如果都满足那就是我们要找的类了。实例化它!注册它!

if (annotation != null && Service.class.isAssignableFrom(aClass)) {
ServiceRegistry.register(annotation.urlPattern(), aClass.asSubclass(Service.class).newInstance());
}

注意这里的 isAssignableFrom 和 instanceof 的差别, isAssignableFrom 左边是右边的父类或者接口。

整个过程就是先获取根目录,然后递归扫描所有.class进行上述判断。而且反射的时候得用全名,那同时再记录一下包路径。具体可以查看源码。

这个过程还遇到了一个问题: 在一开始我获取了edu.telemarketer的包名想转化为路径用的是name.replaceAll("\\.", File.separator)。在windows环境下测试出现了一个异常。经过查证后发现,replaceAll是不准出现"\"的,会引起混淆。于是用Matcher.quoteReplacement(File.separator)进行替代单独的separator。具体点此处 StackOverflow--replaceAll “/” with File.separator

到此为止自动挡就弄完了。

Connector里的使用

还记得第一章读取事件里面的Connector吗,它是一个实现了Runnable的类. 它的run里面大概是这么一个过程。

 Request request = Request.parseRequest(channel);
Service service =ServiceRegistry.findService(request.getFilePath());
Response response = service.execute(request);
channel.register(selector, SelectionKey.OP_WRITE, response);

启动一下,看看页面是不是出来了。


在提交给service处理前和处理后应该由服务器先对头域中的一些信息进行处理,比如维护连接或者处理cookie等等。这些方面后续再来完善。

徒手用Java来写个Web服务器和框架吧<第三章:Service的实现和注册>的更多相关文章

  1. 徒手用Java来写个Web服务器和框架吧<第一章:NIO篇>

    因为有个不会存在大量连接的小的Web服务器需求,不至于用上重量级服务器,于是自己动手写一个服务器. 同时也提供了一个简单的Web框架.能够简单的使用了. 大体的需求包括 能够处理HTTP协议. 能够提 ...

  2. 徒手用Java来写个Web服务器和框架吧<第二章:Request和Response>

    徒手用Java来写个Web服务器和框架吧<第一章:NIO篇> 接上一篇,说到接受了请求,接下来就是解析请求构建Request对象,以及创建Response对象返回. 多有纰漏还请指出.省略 ...

  3. java写的web服务器

    经常用Tomcat,不知道的以为Tomcat很牛,其实Tomcat就是用java写的,Tomcat对jsp的支持做的很好,那么今天我们用java来写一个web服务器 //首先得到一个server, S ...

  4. 用java写一个web服务器

    一.超文本传输协议 Web服务器和浏览器通过HTTP协议在Internet上发送和接收消息.HTTP协议是一种请求-应答式的协议——客户端发送一个请求,服务器返回该请求的应答.HTTP协议使用可靠的T ...

  5. 用C写一个web服务器(二) I/O多路复用之epoll

    .container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...

  6. 转:C#写的WEB服务器

    转:http://www.cnblogs.com/x369/articles/79245.html 这只是一个简单的用C#写的WEB服务器,只实现了get方式的对html文件的请求,有兴趣的朋友可以在 ...

  7. 各种容器与服务器的区别与联系 Servlet容器 WEB容器 Java EE容器 应用服务器 WEB服务器 Java EE服务器

    转自:https://blog.csdn.net/tjiyu/article/details/53148174 各种容器与服务器的区别与联系 Servlet容器 WEB容器 Java EE容器 应用服 ...

  8. 使用node.js 文档里的方法写一个web服务器

    刚刚看了node.js文档里的一个小例子,就是用 node.js 写一个web服务器的小例子 上代码 (*^▽^*) //helloworld.js// 使用node.js写一个服务器 const h ...

  9. Tomcat源码分析 (一)----- 手写一个web服务器

    作为后端开发人员,在实际的工作中我们会非常高频地使用到web服务器.而tomcat作为web服务器领域中举足轻重的一个web框架,又是不能不学习和了解的. tomcat其实是一个web框架,那么其内部 ...

随机推荐

  1. @pathvariable 注解

    1.4. @PathVariable 注解 带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义 通过 @PathVar ...

  2. delphi公用函数

    {*******************************************************} { } { Delphi公用函数单元 } { } { 版权所有 (C) 2008 } ...

  3. Could not execute auto check for display colors using command /usr/bin/xdpyinfo.(

    Steps to resolve this issue: 1) login into root user( su -l root) 2) execute this command : xhost +S ...

  4. Java学习之旅基础知识篇:数据类型及流程控制

    经过开篇对Java运行机制及相关环境搭建,本篇主要讨论Java程序开发的基础知识点,我简单的梳理一下.在讲解数据类型之前,我顺便提及一下Java注释:单行注释.多行注释以及文档注释,这里重点强调文档注 ...

  5. Canvas get/putImageData

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 2017《JAVA技术》预备作业

    1.阅读邹欣老师的博客,谈谈你期望的师生关系是什么样的? ==我期望的师生关系是长辈和晚辈,前辈和后生,朋友与朋友之间的关系,作为晚辈,要尊敬长辈,不能对长辈进行言语攻击和起冲突:作为后生,要谨遵教诲 ...

  7. 《JAVASCRIPT高级程序设计》错误处理与调试

    一.错误处理 错误处理在程序设计中的重要性是毋庸置疑的,任何有影响力的web应用程序都需要一套完善的错误处理机制.良好的错误机制可以让用户得到提醒,知道发生了什么事. 1.try-catch语句 tr ...

  8. 学习window系统下的注册表

    一直不明白注册表是一个什么鬼,查了资料后大概明白了注册表到底有什么用,其实简单来说注册表就是一个存放系统.硬件.应用配置信息的数据ku.##### 一.注册表的来历在最早的视窗操作系统win3.x中, ...

  9. Java IO流学习总结三:缓冲流-BufferedInputStream、BufferedOutputStream

    Java IO流学习总结三:缓冲流-BufferedInputStream.BufferedOutputStream 转载请标明出处:http://blog.csdn.net/zhaoyanjun6/ ...

  10. Leaflet+heatmap实现离线地图加载和热力图应用

    本人博客主页:http://www.cnblogs.com/webbest/ 2017年春节已经过完,新一年的奋斗也刚刚开始.今年要经历的挑战也是大大的...不扯了. 年底前软件项目相对较多,恰巧在年 ...