一步一步编写自己的Web MVC框架——Action中方法的装载
来源:互联网 发布:苹果anywhere软件 编辑:程序博客网 时间:2024/06/06 16:24
我准备用一个@MyActionde 的注解,来配上需要装载进入方法容器的类,自定义在类上写上@MyAction(value="/root"),则代码访问该类需要"/root"根路径,然后在方法上加上@MyAction(value = "/test"),表示执行该方法的路径为,“/root/test”。
package action;import myframe.annotation.MyAction;import myframe.annotation.MyMethod;/** * Created by yuyufeng on 2017/5/5. */@MyAction(value="/root")public class TestAction { @MyAction(value = "/test") public String testMyMethod() { System.out.println("TestAction.testMyMethod"); return "index"; } @MyAction(value = "/test2") public String testMyMethod2() { System.out.println("TestAction.testMyMethod2"); return "test"; }}
在容器map中,设计路径为键,要执行的类方法为值。
注解MyAction
package myframe.annotation;import java.lang.annotation.*;/** * Created by yuyufeng on 2017/5/5. */@Target({ElementType.TYPE, ElementType.METHOD})@Retention(value = RetentionPolicy.RUNTIME)@Documented@Inheritedpublic @interface MyAction { String value() default "";}
Map容器中值为类方法,所以先设计类结构ActionBean如下:
package myframe.bean;import java.lang.reflect.Method;/** * Created by yuyufeng on 2017/5/5. */public class ActionBean { private Class<?> clazz; private Method method; public ActionBean(Class<?> clazz, Method method) { this.clazz = clazz; this.method = method; } public Class<?> getClazz() { return clazz; } public void setClazz(Class<?> clazz) { this.clazz = clazz; } public Method getMethod() { return method; } public void setMethod(Method method) { this.method = method; }}
整理一下思路就是,通过uri去执行一个对象实例中的某个方法。
所以,我们需要两个容器。一个容器装载Action类实例,一个容器装载uri和ActionBean。
因为我们是通过方法调用的,所以只需要一个实例就好,一个Action放如一个实例到容器即可。(这个容器也类似Spring的IOC管理bean)
在反射过程中,我们需要从项目的package中获取带有@MyAction注解的类和方法,我们需要一个类扫描器,
类扫描工具类如下:
ClassUtil.java
我们执行一个junit测试类,去执行扫描执行。
Action实例:
package action;import myframe.annotation.MyAction;/** * Created by yuyufeng on 2017/5/5. */@MyAction(value="/root")public class TestAction { @MyAction(value = "/test") public String testMyMethod() { System.out.println("TestAction.testMyMethod"); return "index"; } @MyAction(value = "/test2") public String testMyMethod2() { System.out.println("TestAction.testMyMethod2"); return "test"; }}
test:
import myframe.annotation.MyAction;import myframe.bean.ActionBean;import myframe.commons.ClassUtil;import org.junit.Test;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;import java.util.Set;/** * Created by yuyufeng on 2017/5/5. */public class TestAnno { private static Map<String, ActionBean> map = new HashMap<String, ActionBean>(); private static Map<Class<?>, Object> objectMap = new HashMap<Class<?>, Object>(); @Test public void test() throws IllegalAccessException, InstantiationException { Set<Class<?>> classes = ClassUtil.getClasses("action"); for (Class<?> aClass : classes) { System.out.println(aClass); if (aClass.isAnnotationPresent(MyAction.class)) { MyAction mac = aClass.getAnnotation(MyAction.class); String classAnnoValue = mac.value().trim(); objectMap.put(aClass,aClass.newInstance()); for (Method method : aClass.getMethods()) { if (method.isAnnotationPresent(MyAction.class)) { MyAction mam = method.getAnnotation(MyAction.class); String methodAnnoValue = mam.value().trim(); String actionName = classAnnoValue + methodAnnoValue; map.put(actionName,new ActionBean(aClass,method)); } } } } ActionBean ab = map.get("/root/test2"); System.out.println(ab); try { String result= (String) ab.getMethod().invoke(objectMap.get(ab.getClazz())); System.out.println(result); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } }}
执行结果:
Connected to the target VM, address: '127.0.0.1:59438', transport: 'socket'class action.TestActionmyframe.bean.ActionBean@475530b9TestAction.testMyMethod2testDisconnected from the target VM, address: '127.0.0.1:59438', transport: 'socket'Process finished with exit code 0
到这一步,根据uri反射执行类方法已经初步实现。
这些方法在框架初始化阶段执行装载即可。
建立一个初始化执行类:
package myframe.init;import myframe.annotation.MyAction;import myframe.bean.ActionBean;import myframe.commons.ClassUtil;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;import java.util.Set;/** * Created by yuyufeng on 2017/5/5. */public class MyFrameInit { private static Map<String, ActionBean> actionMap; private static Map<Class<?>, Object> objectMap; public static Object getObject(Class<?> clazz) { return objectMap.get(clazz); } public static ActionBean getActionBean(String key) { return actionMap.get(key); } public static void init() throws IllegalAccessException, InstantiationException { actionMap = new HashMap<String, ActionBean>(); objectMap = new HashMap<Class<?>, Object>(); Set<Class<?>> classes = ClassUtil.getClasses("action"); for (Class<?> aClass : classes) { System.out.println(aClass); if (aClass.isAnnotationPresent(MyAction.class)) { MyAction mac = aClass.getAnnotation(MyAction.class); String classAnnoValue = mac.value().trim(); objectMap.put(aClass, aClass.newInstance()); for (Method method : aClass.getMethods()) { if (method.isAnnotationPresent(MyAction.class)) { MyAction mam = method.getAnnotation(MyAction.class); String methodAnnoValue = mam.value().trim(); String actionName = classAnnoValue + methodAnnoValue; actionMap.put(actionName, new ActionBean(aClass, method)); } } } } System.out.println("MyFrameInit.init==================初始化完毕"); }}
然后,我们在入口Servlet第一次执行的时候去调用初始化方法:
public class MyFrameServlet extends HttpServlet { @Override public void init(ServletConfig config) throws ServletException { try { MyFrameInit.init(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } }
入口Servlet的doGet完善
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取要执行的动作 String uri = req.getRequestURI(); String actionName = uri.substring(0, uri.indexOf(".do")); System.out.println("访问Action:" + actionName); //do ActionBean actionBean = MyFrameInit.getActionBean(actionName); String result = ""; try { result = (String) actionBean.getMethod().invoke(MyFrameInit.getObject(actionBean.getClazz())); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } //return String fileName = result; System.out.println("执行完毕,跳转路径"+"/WEB-INF/jsp/" + fileName + ".jsp"); req.getRequestDispatcher("/WEB-INF/jsp/" + fileName + ".jsp").forward(req, resp); }
配置tomcat,启动
访问http://127.0.0.1:8080/root/test.do
访问http://127.0.0.1:8080/root/test2.do
日志打印:
class action.TestActionMyFrameInit.init==================初始化完毕访问Action:/root/testTestAction.testMyMethod执行完毕,跳转路径/WEB-INF/jsp/index.jsp访问Action:/root/test2TestAction.testMyMethod2执行完毕,跳转路径/WEB-INF/jsp/test.jsp
现在,页面的控制以及服务器方法的执行已经成功了。
阅读全文
1 0
- 一步一步编写自己的Web MVC框架——Action中方法的装载
- 一步一步编写自己的Web MVC框架——前言
- 一步一步编写自己的Web MVC框架——属性自动获取和传递
- 一步一步编写自己的Web MVC框架——web项目的建立和基本架构的确认
- 利用 Composer 一步一步构建自己的 PHP 框架(三)——设计 MVC
- 如何编写自己的PHP MVC 框架
- 自己编写基于MVC的轻量级PHP框架.
- 手把手编写自己的PHP MVC框架实例教程
- 自己编写的MVC框架实践(一)
- 自己编写的MVC框架实践(二)
- 手把手编写自己的 PHP MVC 框架实例教程
- 手把手编写自己的PHP MVC框架实例教程
- 手把手编写自己的PHP MVC框架实例教程
- 手把手编写自己的PHP MVC框架实例教程
- 从零开始编写自己的C#框架(15)——Web层后端登陆功能
- struts2框架编写web的基本方法
- 利用 Composer 完善自己的 PHP 框架(一)——视图装载
- 利用 Composer 完善自己的 PHP 框架(一)——视图装载
- USACO
- Linux启动过程(开机启动顺序)
- FFmpeg Basics阅读笔记1:介绍
- 私有地址 公有地址
- SQLSever触发器建立
- 一步一步编写自己的Web MVC框架——Action中方法的装载
- CentOS搭建LAMP环境
- shell表达式详解
- 欢迎使用CSDN-markdown编辑器
- js传值到后台,后台发生乱码问题
- Swift
- pandas之索引、选取和过滤
- 【精华】十二大最著名的Android播放器开源项目
- ★codeforces 612D The Union of k-Segments (思维or类扫描线)