diy面向请求的java框架

这个框架也是为google app engine准备的。当时感觉直接在gae上sevlet太烦人了,就封装个简易的框架。使用的时候只需要配置web.xml中DispacherSevlet和package.properties中的package.path(默认扫描的包)即可
gae例子: http://orzblogs.appspot.com/Home.htm    (记得自己找梯子。。。)

首先声明:gae本身就是个玩具。这个web框架也是为了玩玩具而做的玩具。。。性能很有问题,不过gae上也无所谓了。不用多久conetxt就全被清空了。所以全当玩具玩吧,理念可以可以看下。
大学的时候很BS java,学了之后就扔掉了,现在工作了才开始接触java。
java在web方面如果不是开源,不是众多的java框架支持,那么它确实没什么值得称道的。
倒是jvm被优化的不错。

java web框架本质上都是sevlet,所有的那么web框架都是对sevlet进行了封装,然后对web相关的进行包装。那么我们也可以来diy个简易的web框架,为的是体验这个中间的过程,可能框架不实用,甚至不能称作框架,其实为的就是减少一点配置,虽然现在springMVC通过注解就可以减少web层的配置,这里所做的也是同样的事,性能肯定很差,但是也是一种方法,增加理解而已。

首先任何web框架的入口基本上都是一个XXdispatcher。用来进行请求url的转发。
OK,那么我们就来做一个面向web请求的简易的不能称为框架的框架。前端使用velicity进行渲染。
当然一定要把spring给集成进来,要不谁给我们持久化bean呢。

首先通过DispacherSevlet来进行请求的转发。然后根据请求的名称加载bean。然后通过反射将bean的相关属性注入。然后执行bean。然后获取需要渲染的模板。渲染。返回结果给用户。

Java代码 复制代码
  1. public String doGet(HttpRequest request, HttpResponse response, Map<String, Object> context)   
  2. public String doPost(HttpRequest request, HttpResponse response, Map<String, Object> context)  
public String doGet(HttpRequest request, HttpResponse response, Map<String, Object> context)
public String doPost(HttpRequest request, HttpResponse response, Map<String, Object> context)

用户请求/Home.htm然后获取到对应的controller为Home。然后从框架IOC中获取Home。如果获取不到就通过bean加载器来加载Home,然后通过Home的dopost或者doget方法来处理应用。dopost和doget中会放入映射进去一个map<string,object>来存页面的上下文。当处理完毕后根据Home返回的页面路径来进行页面渲染,并将结果返回给用户。


细节:
1.维护一个自己的上下文用来存储所有的controller。当请求来的时候。先看上下文中是否存在这个controller,如果存在就不用去创建了,如果不存在创建之并且缓存到上下文中。
2.维护一个spring的上下文,当创建bean的时候从spring中获取相应的bean反射到要创建的bean相应的属性中。
3.前端用velicity进行渲染。实现control和主页面信息的隔离渲染。


使用步骤:
1.将jar包导入
2.配置web.xml中
Xml代码 复制代码
  1. <servlet>  
  2.         <servlet-name>dispatcher</servlet-name>  
  3.         <servlet-class>org.jeasy.core.DispacherServlet</servlet-class>  
  4.     </servlet>  
<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.jeasy.core.DispacherServlet</servlet-class>
	</servlet>

3.在package.properties中的package.path包下增加类(如果访问Home.htm就增加Home.java
4.Home.java实现Controller接口,然后return 一个String类型,String为vm模板



核心代码:
DispacherSevlet
Java代码 复制代码
  1. public class DispacherServlet extends HttpServlet {   
  2.     private static final long        serialVersionUID = 1L;   
  3.     private XmlWebApplicationContext applicationContext;   
  4.     private BeanLoaderService        beanLoaderService;   
  5.     private PathResolver             pathResolver;   
  6.     private ViewResolver viewResolver;   
  7.     private FrameWorkFlowManager frameWorkFlowManager;   
  8.   
  9.     /**  
  10.      * 初始化应用信息  
  11.      *   
  12.      * @param config  
  13.      * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)  
  14.      */  
  15.     public void init(ServletConfig servletConfig) throws ServletException {   
  16.         //初始化spring IOC   
  17.         applicationContext = new XmlWebApplicationContext();   
  18.         applicationContext.setServletConfig(servletConfig);   
  19.         applicationContext.refresh();   
  20.   
  21.         //初始化jeasy IOC   
  22.         JEasyApplicationContext jEasyApplicationContext = new JEasyApplicationContext();           
  23.   
  24.         //初始化bean加载器   
  25.         beanLoaderService = new BeanLoaderService(servletConfig.getServletContext(),applicationContext, jEasyApplicationContext);   
  26.   
  27.         //初始化请求解析器   
  28.         pathResolver = new PathResolver();   
  29.   
  30.         //初始化渲染器   
  31.         viewResolver=new VelocityResolver(servletConfig.getServletContext());   
  32.            
  33.         //初始化工作流处理器   
  34.         frameWorkFlowManager=new FrameWorkFlowManager();    
  35.            
  36.         super.init(servletConfig);   
  37.     }   
  38.        
  39.     /**  
  40.      * 通过service来处理请求,不用以前的doPost和doGet  
  41.      * @param request  
  42.      * @param response  
  43.      * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)  
  44.      */  
  45.     public  void service(HttpServletRequest request, HttpServletResponse response){   
  46.         HttpRequest httpRequest = new HttpRequest(request);   
  47.         HttpResponse httpResponse = new HttpResponse(response);   
  48.            
  49.         //初始化工作流处理器   
  50.         frameWorkFlowManager.init(beanLoaderService, viewResolver, httpRequest, httpResponse);   
  51.            
  52.         //获取请求的地址信息   
  53.         String requestPath = request.getServletPath();   
  54.         String path=pathResolver.getPath(requestPath);   
  55.            
  56.         //装备、执行、渲染   
  57.         frameWorkFlowManager.work(path);   
  58.     }   
  59. }  
public class DispacherServlet extends HttpServlet {
    private static final long        serialVersionUID = 1L;
    private XmlWebApplicationContext applicationContext;
    private BeanLoaderService        beanLoaderService;
    private PathResolver             pathResolver;
    private ViewResolver viewResolver;
    private FrameWorkFlowManager frameWorkFlowManager;

    /**
     * 初始化应用信息
     * 
     * @param config
     * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
     */
    public void init(ServletConfig servletConfig) throws ServletException {
        //初始化spring IOC
        applicationContext = new XmlWebApplicationContext();
        applicationContext.setServletConfig(servletConfig);
        applicationContext.refresh();

        //初始化jeasy IOC
        JEasyApplicationContext jEasyApplicationContext = new JEasyApplicationContext();        

        //初始化bean加载器
        beanLoaderService = new BeanLoaderService(servletConfig.getServletContext(),applicationContext, jEasyApplicationContext);

        //初始化请求解析器
        pathResolver = new PathResolver();

        //初始化渲染器
        viewResolver=new VelocityResolver(servletConfig.getServletContext());
        
        //初始化工作流处理器
        frameWorkFlowManager=new FrameWorkFlowManager(); 
        
        super.init(servletConfig);
    }
    
    /**
     * 通过service来处理请求,不用以前的doPost和doGet
     * @param request
     * @param response
     * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    public  void service(HttpServletRequest request, HttpServletResponse response){
        HttpRequest httpRequest = new HttpRequest(request);
        HttpResponse httpResponse = new HttpResponse(response);
		
        //初始化工作流处理器
        frameWorkFlowManager.init(beanLoaderService, viewResolver, httpRequest, httpResponse);
        
        //获取请求的地址信息
        String requestPath = request.getServletPath();
        String path=pathResolver.getPath(requestPath);
        
        //装备、执行、渲染
        frameWorkFlowManager.work(path);
    }
}

首先在第一次创建的时候会初始化springIOC容器、自己的IOC容器、web层bean加载器、地址转换器、页面渲染、工作流

首先获请求的地址,然后进入工作流

BeanLoadService
Java代码 复制代码
  1. /**  
  2.  * bean的装配器  
  3.  *   
  4.  * @author yuezhen  
  5.  * @version $Id: ControllerLoadService.java,v 0.1 2009-9-24 上午09:35:09 yuezhen Exp $  
  6.  */  
  7. public class BeanLoaderService {   
  8.     private static final Logger     logger = Logger.getLogger(BeanLoaderService.class.getName());   
  9.     private ApplicationContext      applicationContext;   
  10.     private JEasyApplicationContext jEasyContext;   
  11.     private String packagePath;   
  12.   
  13.     /**  
  14.      * 获取spring的ioc容器和jeasy的ioc容器  
  15.      * @param applicationContext spring的ioc容器  
  16.      */  
  17.     public BeanLoaderService(ServletContext servletContext,ApplicationContext applicationContext,   
  18.                              JEasyApplicationContext jEasyContext) {   
  19.         this.applicationContext = applicationContext;   
  20.         this.jEasyContext = jEasyContext;   
  21.            
  22.         String rootPath = servletContext.getRealPath("/");   
  23.   
  24.         logger.info("[jeasy] rootPath="+rootPath);   
  25.            
  26.         Properties properties = new Properties();   
  27.         try {   
  28.             properties.load(new FileInputStream(rootPath   
  29.                     + "/WEB-INF/package.properties"));   
  30.         } catch (Exception e) {   
  31.             logger.warning("[jeasy] can't load package.properties,rootPath="+rootPath);   
  32.         }   
  33.   
  34.         packagePath = properties.getProperty("package.path","");   
  35.         if(!packagePath.equals("")){   
  36.             packagePath=packagePath+".";   
  37.         }   
  38.     }   
  39.   
  40.     /**  
  41.      * 获取Controller  
  42.      * 如果在jeasy IOC中存在,直接读取  
  43.      * 如果在jeasy IOC中不存在,创建Controller,并放入jeasy IOC  
  44.      */  
  45.     public Controller getController(String name) {   
  46.         if (StringUtils.isBlank(name)) {   
  47.             return null;   
  48.         }   
  49.   
  50.         Controller jEasyController = null;   
  51.         jEasyController = jEasyContext.getController(packagePath+name);   
  52.   
  53.         //在jeasy IOC中不存在,创建Controller并存入IOC   
  54.         if (jEasyController == null) {   
  55.             logger.info("init bean:"+packagePath+name);   
  56.             jEasyController = this.createController(packagePath+name);   
  57.             jEasyContext.addController(packagePath+name, jEasyController);   
  58.         }   
  59.   
  60.         return jEasyController;   
  61.     }   
  62.   
  63.     /**  
  64.      * 通过反射创建controller  
  65.      * @param name  
  66.      * @return  
  67.      */  
  68.     public Controller createController(String name) {   
  69.         Controller controller = null;   
  70.         try {   
  71.             //获取controller   
  72.             controller = (Controller) Class.forName(name).newInstance();   
  73.   
  74.             //包装controller,将set方法注入   
  75.             buildController(controller);   
  76.         } catch (ClassNotFoundException e) {   
  77.             logger.warning("[jeasy] can't find class named " + name);   
  78.         } catch (InstantiationException e) {   
  79.         } catch (IllegalAccessException e) {   
  80.         }   
  81.         return controller;   
  82.     }   
  83.   
  84.     /**  
  85.      * 将controller里面所有的set方法全部注入  
  86.      * @param controller  
  87.      */  
  88.     public void buildController(Controller controller) {   
  89.         Class jEasyClass = controller.getClass();   
  90.         Field[] fields = jEasyClass.getDeclaredFields();   
  91.         for (Field field : fields) {   
  92.             String fieldName = field.getName();   
  93.             String method = "set" + fieldName.substring(01).toUpperCase()   
  94.                             + fieldName.substring(1);   
  95.   
  96.             try {   
  97.                 Method setMethod = jEasyClass.getMethod(method, new Class<?>[] { field.getType() });   
  98.                 // 从springIOC中取得bean   
  99.                 Object bean = applicationContext.getBean(field.getName());   
  100.                 if(bean!=null){   
  101.                     setMethod.invoke(controller, bean);   
  102.                 }   
  103.             } catch (SecurityException e) {   
  104.             } catch (NoSuchMethodException e) {   
  105.             } catch (IllegalArgumentException e) {   
  106.             } catch (IllegalAccessException e) {   
  107.             } catch (InvocationTargetException e) {   
  108.             }   
  109.   
  110.         }   
  111.     }   
  112. }  
/**
 * bean的装配器
 * 
 * @author yuezhen
 * @version $Id: ControllerLoadService.java,v 0.1 2009-9-24 上午09:35:09 yuezhen Exp $
 */
public class BeanLoaderService {
    private static final Logger     logger = Logger.getLogger(BeanLoaderService.class.getName());
    private ApplicationContext      applicationContext;
    private JEasyApplicationContext jEasyContext;
    private String packagePath;

    /**
     * 获取spring的ioc容器和jeasy的ioc容器
     * @param applicationContext spring的ioc容器
     */
    public BeanLoaderService(ServletContext servletContext,ApplicationContext applicationContext,
                             JEasyApplicationContext jEasyContext) {
        this.applicationContext = applicationContext;
        this.jEasyContext = jEasyContext;
        
        String rootPath = servletContext.getRealPath("/");

        logger.info("[jeasy] rootPath="+rootPath);
        
        Properties properties = new Properties();
		try {
			properties.load(new FileInputStream(rootPath
					+ "/WEB-INF/package.properties"));
		} catch (Exception e) {
			logger.warning("[jeasy] can't load package.properties,rootPath="+rootPath);
		}

		packagePath = properties.getProperty("package.path","");
		if(!packagePath.equals("")){
			packagePath=packagePath+".";
		}
    }

    /**
     * 获取Controller
     * 如果在jeasy IOC中存在,直接读取
     * 如果在jeasy IOC中不存在,创建Controller,并放入jeasy IOC
     */
    public Controller getController(String name) {
        if (StringUtils.isBlank(name)) {
            return null;
        }

        Controller jEasyController = null;
        jEasyController = jEasyContext.getController(packagePath+name);

        //在jeasy IOC中不存在,创建Controller并存入IOC
        if (jEasyController == null) {
            logger.info("init bean:"+packagePath+name);
            jEasyController = this.createController(packagePath+name);
            jEasyContext.addController(packagePath+name, jEasyController);
        }

        return jEasyController;
    }

    /**
     * 通过反射创建controller
     * @param name
     * @return
     */
    public Controller createController(String name) {
        Controller controller = null;
        try {
            //获取controller
            controller = (Controller) Class.forName(name).newInstance();

            //包装controller,将set方法注入
            buildController(controller);
        } catch (ClassNotFoundException e) {
            logger.warning("[jeasy] can't find class named " + name);
        } catch (InstantiationException e) {
        } catch (IllegalAccessException e) {
        }
        return controller;
    }

    /**
     * 将controller里面所有的set方法全部注入
     * @param controller
     */
    public void buildController(Controller controller) {
        Class jEasyClass = controller.getClass();
        Field[] fields = jEasyClass.getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName();
            String method = "set" + fieldName.substring(0, 1).toUpperCase()
                            + fieldName.substring(1);

            try {
                Method setMethod = jEasyClass.getMethod(method, new Class<?>[] { field.getType() });
                // 从springIOC中取得bean
                Object bean = applicationContext.getBean(field.getName());
                if(bean!=null){
                    setMethod.invoke(controller, bean);
                }
            } catch (SecurityException e) {
            } catch (NoSuchMethodException e) {
            } catch (IllegalArgumentException e) {
            } catch (IllegalAccessException e) {
            } catch (InvocationTargetException e) {
            }

        }
    }
}

在bean加载器中会根据请求的url来加载bean。比如:请求/Home.htm,那么地址转化器会获取到bean的name为Home。然后会去加载Home的bean来当作Home的controller。将所有需要set的方法从SpringIOC中读出进行set,然后将Home以string,object的形式进行缓存。


FrameWorkFlowManager
Java代码 复制代码
  1. public class FrameWorkFlowManager {   
  2.     private static final Logger logger = Logger   
  3.             .getLogger(FrameWorkFlowManager.class.getName());   
  4.     private BeanLoaderService beanLoaderService;   
  5.     private ViewResolver viewResolver;   
  6.     private HttpRequest request;   
  7.     private HttpResponse response;   
  8.   
  9.     public void init(BeanLoaderService beanLoaderService,   
  10.             ViewResolver viewResolver, HttpRequest request,   
  11.             HttpResponse response) {   
  12.         this.beanLoaderService = beanLoaderService;   
  13.         this.viewResolver = viewResolver;   
  14.         this.request = request;   
  15.         this.response = response;   
  16.         setResonse();   
  17.     }   
  18.   
  19.     public void work(String path) {   
  20.   
  21.         // 每次进行页面渲染,每个页面一个上下文   
  22.         Map<String, Object> context = new HashMap<String, Object>();   
  23.         Control control=new Control(viewResolver, response,context, request,beanLoaderService);   
  24.   
  25.         context.put("control", control);   
  26.            
  27.         render(path,context);   
  28.     }   
  29.   
  30.     public void render(String path,Map<String, Object> context) {   
  31.         Controller controller = null;   
  32.         try {   
  33.             // 获取控制器对象   
  34.             controller = beanLoaderService.getController(path);   
  35.         } catch (Exception e) {   
  36.         }   
  37.   
  38.         if (controller != null) {   
  39.             String result = null;   
  40.             try {   
  41.                 // 调用Controller处理   
  42.                 if (controller != null) {   
  43.   
  44.                     if (request.getMethod().equals("POST")) {   
  45.                         result = controller.doPost(request, response, context);   
  46.                     } else {   
  47.                         result = controller.doGet(request, response, context);   
  48.                     }   
  49.                 } else {   
  50.                     response.sendError(404);   
  51.                     return;   
  52.                 }   
  53.             } catch (Exception e) {   
  54.             }   
  55.   
  56.             logger.info(result);   
  57.   
  58.             try {   
  59.                 if (result != null) {   
  60.                     if (result.startsWith("redirect:")) {   
  61.                         response.sendRedirect(result.substring("redirect:"  
  62.                                 .length()));   
  63.                     } else {   
  64.                         viewResolver.merge(result, context, response);   
  65.                     }   
  66.                 }   
  67.             } catch (Exception e) {   
  68.             }   
  69.         }   
  70.     }   
  71.        
  72.     private void setResonse(){   
  73.         response.setCharacterEncoding(viewResolver.getCharacterEncoding());   
  74.     }   
  75. }  
public class FrameWorkFlowManager {
	private static final Logger logger = Logger
			.getLogger(FrameWorkFlowManager.class.getName());
	private BeanLoaderService beanLoaderService;
	private ViewResolver viewResolver;
	private HttpRequest request;
	private HttpResponse response;

	public void init(BeanLoaderService beanLoaderService,
			ViewResolver viewResolver, HttpRequest request,
			HttpResponse response) {
		this.beanLoaderService = beanLoaderService;
		this.viewResolver = viewResolver;
		this.request = request;
		this.response = response;
		setResonse();
	}

	public void work(String path) {

		// 每次进行页面渲染,每个页面一个上下文
		Map<String, Object> context = new HashMap<String, Object>();
		Control control=new Control(viewResolver, response,context, request,beanLoaderService);

		context.put("control", control);
		
		render(path,context);
	}

	public void render(String path,Map<String, Object> context) {
		Controller controller = null;
		try {
			// 获取控制器对象
			controller = beanLoaderService.getController(path);
		} catch (Exception e) {
		}

		if (controller != null) {
			String result = null;
			try {
				// 调用Controller处理
				if (controller != null) {

					if (request.getMethod().equals("POST")) {
						result = controller.doPost(request, response, context);
					} else {
						result = controller.doGet(request, response, context);
					}
				} else {
					response.sendError(404);
					return;
				}
			} catch (Exception e) {
			}

			logger.info(result);

			try {
				if (result != null) {
					if (result.startsWith("redirect:")) {
						response.sendRedirect(result.substring("redirect:"
								.length()));
					} else {
						viewResolver.merge(result, context, response);
					}
				}
			} catch (Exception e) {
			}
		}
	}
	
	private void setResonse(){
		response.setCharacterEncoding(viewResolver.getCharacterEncoding());
	}
}


对应的Spring、log4j的jar都要导入一块使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值