一个简单的自定义web框架

来源:互联网 发布:汽车设计软件 编辑:程序博客网 时间:2024/05/16 07:00
只有一个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);
     }
}



0 0
原创粉丝点击