基于NonoHTTPD搭建的get,post请求服务器框架---框架入门

来源:互联网 发布:手游cfbug软件 编辑:程序博客网 时间:2024/05/16 11:04

概述

一句话说的好,没有反射就没有框架。反射可以在运行时对自身状态的读取,虽然效率比较低,但在调用次数较少或对效率不敏感的项目中运用可以非常好的解耦和加快开发效率。对于提高开发效率,注解也是一种很好的方法,一般注解都是配合反射一起使用。

基本技术

注解和反射的简单使用方法

类Class是类运行的实例,通过它可以得到Field,Constructor和Method.

注解定义:

    @Target(ElementType.TYPE)    @Retention(RetentionPolicy.RUNTIME)    public @interface ActionHandle {        public String actionName() default "/";    }

解析:@Target(ElementType.TYPE) 注解类型

  • TYPE 表示可用在类上
  • METHOD 表示可用在方法上
  • FIELD 表示可用在成员变量上
    其他参见jdk文档

@Retention(RetentionPolicy.RUNTIME)表示在哪个级别可用

  • RUNTIME 运行时
  • CLASS 类文件中
  • SOURCE 源码中

default是设定默认值

注解使用:

@ActionHandle(actionName="/login")public class LoginAction implements Action{    public LoginAction() {        // TODO Auto-generated constructor stub    }    @Override    public String doPost(String body) {        // TODO Auto-generated method stub        return "loginsucess";    }    @Override    public String doGet(Map<String, String> parms) {        return "loginsucess";    }}

在类上面加上@ActionHandle(actionName=”/login”)即可。

注解解析器

没有注解解析器,那注解是没有作用的。

ActionHandle annotation = entryclass.getAnnotation(ActionHandle.class);    if (annotation != null) {        System.out.println(entryclass.getName() + " "                + annotation.actionName());

entryclass是Class实例,通过Class类可以获取注解其上面的annotation。然后就可以取得注解的参数了。

正文:框架搭建

ok,上面说了那么多废话,终于说了我怎么搭建一个小框架,便于开发的。

首先,我们的是需求是服务器接收到get,post请求,然后根据url分发给不同的Action处理(当然这里可以用责任链模式,但是感觉不是那么方便)。因此我这里的做法是:

  1. 服务器启动时扫描代码一遍,找出有ActionHandle的类,并用map记录下来。
  2. 收到请求时,通过url为key的map查到指向的类实例。
  3. 使用反射的方法进行构造实例并调用处理方法
  4. 处理完成返回结果。

这就是基本的处理流程,有什么好处呢?就是每添加一个处理方法时,只需在本类中加上注解,说明要处理的url即可。(注解的好处就是不需要配置文件)

具体代码实现

1. 扫描查有注解类。

public static void scan(Context ctx) {        PathClassLoader classloader = (PathClassLoader) Thread.currentThread()                .getContextClassLoader();        try {            DexFile dexfile1 = new DexFile(ctx.getPackageResourcePath());            Enumeration<String> en = dexfile1.entries();            while (en.hasMoreElements()) {                String entry = en.nextElement();                Class<?> entryclass = dexfile1.loadClass(entry, classloader);                if (entryclass != null) {                    ActionHandle annotation = entryclass                            .getAnnotation(ActionHandle.class);                    if (annotation != null) {                        System.out.println(entryclass.getName() + " "                                + annotation.actionName());                        classMap.put(annotation.actionName(), entryclass);                    }                }            }        } catch (IllegalArgumentException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }

通过上下文获取程序包的路径,然后逐级文件扫描,判断是否有注解,如果有并且是我们需要的注解put到Map中。

2. 通过url分发给不同的Action处理

接收url的服务器参见上篇android websevice服务器建立。

if (classMap.containsKey(url)) {    return (Action) classMap.get(url).newInstance();}

3. Action处理并返回

由于Action实现同一个接口,我们不需要考虑具体的实现,直接调用接口的方法即可。我这里的接口只有dopost和doget方法。定义如下:

public interface Action {    public String doPost(String body);    public String doGet(Map<String, String> parms);}

总结

通过这方法,我们把这框架打成jar包就可以使用了。sample上面loginAciton类。

ps:接口可以按需要自己定义。
我是源码(未上传)

0 0