一个简单的自定义web框架

只有一个servlet,这个servlet处理所有的*.do;
当有请求来时,根据请求的uri,选择对应的action进行处理;
action和uri使用注解来相互映射,中央控制的servlet在启动的时候就扫描classes目录下面的所有class文件,找出带有注解的类,并放入map中,key为uri的值,value为action对象;
需要自定义classloader来加载指定目录下的classes文件;

1.定义注解:
package  com.oterman;

import  java.lang.annotation.Retention;
import  java.lang.annotation.RetentionPolicy;

@Retention (RetentionPolicy. RUNTIME )
public  @interface Control {
     String value();

}

2.定义Action
package  com.oterman;

@Control ( "/book"  )
public  class BookAction {
     
      /**
      * 默认执行该方法
      */
      public  void exec() {
           System. out .println(  "exec()....执行了哦" );
           System. out .println(  this.getClass().getClassLoader());//com.oterman.MyClassLoader@3d637d45
          
     }

      public  void add(){
           System. out .println(  "add()....执行了哦" );
     }
     
      public  void delete(){
           System. out .println(  "delete()....执行了哦" );
     }
}

3.定义中央处理的ControllServlet,该servlet的映射为:
   < servlet  >
     <servlet-name >ControllServlet </servlet-name>
     <servlet-class> com.oterman.ControllServlet</servlet-class >
   </servlet >

   <servlet-mapping >
     <servlet-name >ControllServlet </servlet-name>
     <url-pattern >*.do </url-pattern>
   </servlet-mapping >


ControllServlet.java
package  com.oterman;

import  java.io.ByteArrayOutputStream;
import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileNotFoundException;
import  java.io.IOException;
import  java.lang.reflect.InvocationTargetException;
import  java.lang.reflect.Method;
import  java.util.HashMap;
import  java.util.Map;

import  javax.servlet.ServletException;
import  javax.servlet.http.HttpServlet;
import  javax.servlet.http.HttpServletRequest;
import  javax.servlet.http.HttpServletResponse;

public  class ControllServlet extends HttpServlet {
      private  Map<String, Object> actionMap = null ;

      @Override
      public  void init() throws ServletException {
            super.init();
            //中央处理servlet创建时,扫描classes目录下所有的class文件,找出action的class,并将 uri和对应的action放入到map中去;
            actionMap = new HashMap<String, Object>();
          String classpath =  this.getServletContext().getRealPath("/WEB-INF/classes" );
          File dir =  new File(classpath);
            try {
              scanClass(dir);
          }  catch (Exception e) {
              e.printStackTrace();
          }
          
     }
      //判断一个文件是目录还是文件,如果是文件,判断是否为class文件,如果为class文件,判断是有注解!
      public  void scanClass(File dir) throws Exception {
            if (dir.isDirectory()) {//为目录
              File[] files = dir.listFiles();
                for (File file : files) {
                   scanClass(file);  //迭代操作
              }
          }

            if (dir.isFile()) {//为文件
                if (dir.getName().endsWith(".class" )) {
                     //将硬盘上的class文件读取为byte[];
                   FileInputStream fis =  new FileInputStream(dir);
                   ByteArrayOutputStream bos =  new ByteArrayOutputStream();
                     byte[] buffer = new byte[1024];
                     int len = 0;
                     while ((len = fis.read(buffer)) != -1) {
                        bos.write(buffer, 0, len);
                   }
                   bos.close();
                     byte[] bytes = bos.toByteArray();//class文件的字节码
                   
                     //自定义classloader,将byte[]翻译成class对象
                   MyClassLoader classloader =  new MyClassLoader(this.getClass().getClassLoader());
                    Class clazz =classloader.getClass(bytes);
                   
                     //判断该类上是否有注解,如果有,则放入map中去;
                     Control annotation = ( Control) clazz.getAnnotation(Control.class) ;
                     if (annotation != null) {
                        String uri = annotation.value();
                          actionMap.put(uri, clazz.newInstance());
                   }
              }
          }
     }
     

      public  void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
          
            //获取请求参数的 uri;
          String uri = request.getRequestURI();  // /MySimpleWebFrame/book.do
          String url = request.getRequestURL().toString(); //http://localhost/MySimpleWebFrame/book.do
          
            //截取需要的uri;/book
          uri=uri.substring(uri.lastIndexOf(  "/"), uri.lastIndexOf("." ));
          System.  out.println(uri);
            //根据uri,查找map,得到处理请求的action
          Object action=  actionMap.get(uri);
            if(action==null ){
                throw new RuntimeException("该请求没有对应的action!" );
          }
            //得到请求参数method,调用action相应的方法;
          String methodname=request.getParameter( "method"  );
            if(methodname==null){//如果请求参数没有改方法,则默认执行 exec方法!
              methodname=  "exec";
          }
          Method method=  null;
            try {
               method= action.getClass().getMethod(methodname,  null);
          }  catch (SecurityException e) {
              e.printStackTrace();
          }  catch (NoSuchMethodException e) {
              e.printStackTrace();
                throw new RuntimeException("该action上没有"+methodname+ "方法!");
          }
          
            //调用该方法
            try {
               method.invoke(action,  null);
          }  catch (IllegalArgumentException e) {
              e.printStackTrace();
          }  catch (IllegalAccessException e) {
              e.printStackTrace();
          }  catch (InvocationTargetException e) {
              e.printStackTrace();
          }
          
     }

      public  void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {

          doGet(request, response);
     }

}

/**
 * 自定义类加载器,将byte[]加载为class对象
 *  @author oterman
 *
 */
class  MyClassLoader extends ClassLoader{
      //自定父加载器,按照加载机制进行加载!加载一个类时,都先交给父类加载,父类加载不了,才一级一级往下传!
      public  MyClassLoader(ClassLoader parent) {
            super(parent);
     }

      public  Class getClass(byte[] bytes){
          System.  out.println("myclassloader2...." );
            return defineClass(null, bytes, 0, bytes.length);
     }
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值