简单mvc---模拟Springmvc
Posted javahxm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单mvc---模拟Springmvc相关的知识,希望对你有一定的参考价值。
1、注解篇
Auwowrited
package org.aaron.mvc.annaotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AaronAutowrited String value() default "";
Controller
package org.aaron.mvc.annaotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AaronController String value() default "";
RequestMapping
package org.aaron.mvc.annaotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE,ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AaronRequestMapping String value() default "";
RequestParam
package org.aaron.mvc.annaotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AaronRequestParam String value() default "";
Service
package org.aaron.mvc.annaotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AaronService String value() default "";
2、DispatcherServlet
package org.aaron.mvc.servlet; import java.io.File; import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.aaron.mvc.annaotation.AaronAutowrited; import org.aaron.mvc.annaotation.AaronController; import org.aaron.mvc.annaotation.AaronRequestMapping; import org.aaron.mvc.annaotation.AaronRequestParam; import org.aaron.mvc.annaotation.AaronService; import org.omg.CORBA.Request; public class DispatcherServlet extends HttpServlet List<String> classNames = new ArrayList<String>();// 全类名路径 // //org.aaron.mvc.service.impl+类名 Map<String,Object> beans = new HashMap<>(); Map<String,Object> handlerMap = new HashMap<>(); /** * */ private static final long serialVersionUID = 1L; public void init(ServletConfig config) // ioc // 扫描所有的bean----->扫描所有的class文件 scanPackage("org.aaron"); // spring的做法是写在配置文件中 // 根据类创建对象 doInstance(); doIoc(); buildUrlMapping();//根据url 建立关系 method // 扫描文件 private void scanPackage(String basePackage) URL url = this.getClass().getClassLoader().getResource("/" + basePackage.replaceAll("\\.", "/"));// 获取工作空间的编译路径 System.err.println(url); String fileStr = url.getFile(); File file = new File(fileStr);// 拿到目录下的文件和文件夹 String[] filesStr = file.list(); // Aaron for (String path : filesStr) File filePath = new File(fileStr + path);// org.aaron.mvc if (filePath.isDirectory()) // 判断是文件还是文件夹 文件夹 递归继续找 scanPackage(basePackage + "." + path); else classNames.add(basePackage + "." + filePath.getName());// org.aaron.mvc.xxx.xxxx.class // 根据扫描的类名 实例化 private void doInstance() if (classNames.size() <= 0) System.err.println("扫描失败"); return; // 遍历 扫描到class文件 for (String className : classNames) String cn = className.replace(".class", ""); try Class<?> clazz = Class.forName(cn); // 获取到org.aaron. if (clazz.isAnnotationPresent(AaronController.class)) // 判断是不是有控制场注解 Object instance = clazz.newInstance();// 创建类 实例化的对象 AaronRequestMapping requestMapping = clazz.getAnnotation(AaronRequestMapping.class);//拿到 mapping 注解 String rm = requestMapping.value();//获取到mapping的value beans.put(rm, instance);// else if (clazz.isAnnotationPresent(AaronService.class)) AaronService aaronService = clazz.getAnnotation(AaronService.class); Object instance = clazz.newInstance(); beans.put(aaronService.value(),instance);// else continue; catch (ClassNotFoundException e) // TODO Auto-generated catch block e.printStackTrace(); catch (InstantiationException e) // TODO Auto-generated catch block e.printStackTrace(); catch (IllegalAccessException e) // TODO Auto-generated catch block e.printStackTrace(); //把service 注入到Controller public void doIoc() if(beans.entrySet().size()<=0) System.err.println("没有实例化的类"); //遍历map的实例化的类 for(Map.Entry<String, Object> entry: beans.entrySet()) Object instace = entry.getValue(); Class<?> clazz = instace.getClass(); if(clazz.isAnnotationPresent(AaronController.class)) Field[] fields =clazz.getDeclaredFields(); for(Field field : fields) if(field.isAnnotationPresent(AaronAutowrited.class))//判断当前遍历是否有注解 AaronAutowrited aaronAutowrited = field.getAnnotation(AaronAutowrited.class); String key = aaronAutowrited.value();//获取到 注解的value field.setAccessible(true);//因为是private 无法修改值 try field.set(instace, beans.get(key)); catch (IllegalArgumentException e) // TODO Auto-generated catch block e.printStackTrace(); catch (IllegalAccessException e) // TODO Auto-generated catch block e.printStackTrace(); else continue; else continue; private void buildUrlMapping() if(beans.entrySet().size()<=0)//没有类的实例化 System.err.println("没有类的实例化"); return; for(Map.Entry<String, Object> entry : beans.entrySet()) Object instance = entry.getValue(); Class<?> clazz = instance.getClass(); if(clazz.isAnnotationPresent(AaronController.class)) AaronRequestMapping aaronRequestMapping = clazz.getAnnotation(AaronRequestMapping.class); String classPath = aaronRequestMapping.value();//拿到类上的mapping Method[] methods = clazz.getMethods();//拿到类的方法 for(Method method : methods) if(method.isAnnotationPresent(AaronRequestMapping.class))//判断了方法上面是否有注解 AaronRequestMapping methodMapping = method.getAnnotation(AaronRequestMapping.class); String methodPath = methodMapping.value();//获取到注解的value handlerMap.put(classPath+methodPath, method); else continue; else continue; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException // TODO Auto-generated method stub System.err.println("test1"); this.doPost(req, resp); @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException // TODO Auto-generated method stub //获取请求路径 /项目名/ctrl/method String uri = req.getRequestURI(); String content = req.getContextPath();//获取项目名 String path = uri.replace(content, "");//ctrl/method Method method = (Method)handlerMap.get(path); Object instance = (Object)beans.get("/"+path.split("/")[1]);// ctrl Object[] agrs = hand(req,resp,method); try method.invoke(instance, agrs); catch (IllegalAccessException e) // TODO Auto-generated catch block e.printStackTrace(); catch (IllegalArgumentException e) // TODO Auto-generated catch block e.printStackTrace(); catch (InvocationTargetException e) // TODO Auto-generated catch block e.printStackTrace(); super.doPost(req, resp); //处理参数 private static Object[] hand(HttpServletRequest req, HttpServletResponse resp,Method method) //拿到当前执行的方法有哪些参数 Class<?>[] paramClazzs = method.getParameterTypes(); //根据参数的个数 new一个存放参数的数组 Object[] args = new Object[paramClazzs.length]; int arg_i = 0 ; int index = 0; for(Class<?> paramClazz : paramClazzs) if(ServletRequest.class.isAssignableFrom(paramClazz)) args[arg_i++] = req; if(ServletResponse.class.isAssignableFrom(paramClazz)) args[arg_i++] = resp; Annotation[] paramAns = method.getParameterAnnotations()[index]; if(paramAns.length>0) for(Annotation paramAn : paramAns) if(AaronRequestParam.class.isAssignableFrom(paramAn.getClass())) AaronRequestParam rp = (AaronRequestParam)paramAn; args[arg_i++] = req.getParameter(rp.value()); index++; return args;
3、实战篇
controller代码
package org.aaron.mvc.ctrl; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.aaron.mvc.annaotation.AaronAutowrited; import org.aaron.mvc.annaotation.AaronController; import org.aaron.mvc.annaotation.AaronRequestMapping; import org.aaron.mvc.annaotation.AaronRequestParam; import org.aaron.mvc.service.TestService; @AaronController @AaronRequestMapping("/Aaron") public class TestCtrl @AaronAutowrited("TestServiceImpl") private TestService service; @AaronRequestMapping("/query") public void query(HttpServletRequest request,HttpServletResponse response, @AaronRequestParam("name") String name, @AaronRequestParam("age") String age) String result = service.query(name, age); try PrintWriter out; response.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=utf-8"); out = response.getWriter(); out.write(result); out.close(); catch (IOException e) // TODO Auto-generated catch block e.printStackTrace();
service接口
package org.aaron.mvc.service; public interface TestService String query(String name,String age);
service接口实现
package org.aaron.mvc.service.impl; import org.aaron.mvc.annaotation.AaronService; import org.aaron.mvc.service.TestService; @AaronService("TestServiceImpl") public class TestServiceImpl implements TestService public String query(String name, String age) // TODO Auto-generated method stub return "当前用户:"+name+"年龄"+age ;
以上是关于简单mvc---模拟Springmvc的主要内容,如果未能解决你的问题,请参考以下文章