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的更多相关文章

  1. 使用Java元注解和反射实现简单MVC框架

    Springmvc的核心是DispatcherServlet来进行各种请求的拦截,进而进行后续的各种转发处理.流程图如下: 说明:客户端发出一个http请求给web服务器,web服务器对http请求进 ...

  2. 手写一个简单版的SpringMVC

    一 写在前面 这是自己实现一个简单的具有SpringMVC功能的小Demo,主要实现效果是; 自己定义的实现效果是通过浏览器地址传一个name参数,打印“my name is”+name参数.不使用S ...

  3. PhantomJS实现最简单的模拟登录方案

    以前写爬虫,遇到需要登录的页面,一般都是通过chrome的检查元素,查看登录需要的参数和加密方法,如果网站的加密非常复杂,例如登录qq的,就会很蛋疼 在后面,有了Pyv8,就可以把加密的js文件扔给它 ...

  4. telnet简单操作 模拟请求

    telnet简单操作   模拟请求 一: 二: 三: 按照以上操作即可!

  5. 简单MVC理解与实现

    MVC基本概念 MVC大家不陌生,包含模型(Model).视图(View).控制器(Controller),其中模型用于基本业务逻辑的实现,视图用于响应结果的表示,控制器用于模型控制和请求分派.先放上 ...

  6. [模拟回调] demo1模拟用字符串调用js函数 demo2模拟springmvc controller回调页面js函数

    demo1. 模拟用字符串调用js 函数 function dataQuery() { var strFun = "testCallBack"; var strParam = &q ...

  7. I.MX6 简单电路模拟USB设备的插入

    /**************************************************************************** * I.MX6 简单电路模拟USB设备的插入 ...

  8. C++动态数组简单的模拟二元堆

    //C++动态数组简单的模拟二元堆 #include<iostream> using namespace std; class BinaryHeap { private: int cap; ...

  9. 洛谷[Luogu] 普及村-简单的模拟总结

    题目列表 注明:Level值代表在本难度下的排行.(纯粹本蒟蒻主观评判)注明:Level值代表在本难度下的排行.(纯粹本蒟蒻主观评判)注明:Level值代表在本难度下的排行.(纯粹本蒟蒻主观评判) P ...

  10. 简单mvc框架核心笔记

    简单mvc框架核心笔记 看了thinkphp5的源码,模仿写了一个简单的框架,有一些心得笔记,记录一下 1.目录结构 比较简单,没有tp那么复杂,只是把需要的核心类写了一些. 核心类库放在mykj里, ...

随机推荐

  1. 生产者和消费者模型producer and consumer(单线程下实现高并发)

    #1.生产者和消费者模型producer and consumer modelimport timedef producer(): ret = [] for i in range(2): time.s ...

  2. CBV和FBV用户认证装饰器

    FBV装饰器用户验证 CBV装饰器用户验证 装饰器位置 或 或

  3. windows下sed回车换行符处理

    windows下sed回车换行符处理如果用sed for windows对整个文件进行了编辑,编辑之后一般需要处理回车换行符:rem windows的回车换行符是\r\n,linux的是\n,所以要替 ...

  4. elasticsearch 7.5.0 学习笔记

    温馨提示:电脑端看不到右侧目录的话请减小缩放比例. API操作-- 新建或删除查询索引库 新建索引库 新建index,要向服务器发送一个PUT请求,下面是使用curl命令新建了一个名为test的ind ...

  5. [LeetCode] 15. 3Sum 三数之和

    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...

  6. vue 图片放大镜效果

    插件名称:vue-photo-zoom-pro https://github.com/Mater1996/vue-photo-zoom-pro 效果图  使用: <template> &l ...

  7. Spring Cloud Gateway的全局异常处理

    Spring Cloud Gateway中的全局异常处理不能直接用@ControllerAdvice来处理,通过跟踪异常信息的抛出,找到对应的源码,自定义一些处理逻辑来符合业务的需求. 网关都是给接口 ...

  8. [勘误] Head First Java (2nd edition)中文版勘误

    附上英文原版高清pdf:链接: https://pan.baidu.com/s/1X5Aikj6krROnp3oXuTVl8Q 提取码: f6xd 标注本文: 上面的图是中文译本中的错误 下面的图是英 ...

  9. C#自定义特性的使用

    特性类的使用过程: 第一步:定义一个特性类,定义一些成员来包含验证时需要的数据:第二步:创建特性类实例:创建一个特性类的实例,里面包含着验证某一个属性或者字段需要的数据.将该实例关联到某个属性上面.第 ...

  10. Spark Core知识点复习-1

    Day1111 Spark任务调度 Spark几个重要组件 Spark Core RDD的概念和特性 生成RDD的两种类型 RDD算子的两种类型 算子练习 分区 RDD的依赖关系 DAG:有向无环图 ...