简单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的更多相关文章
- 使用Java元注解和反射实现简单MVC框架
Springmvc的核心是DispatcherServlet来进行各种请求的拦截,进而进行后续的各种转发处理.流程图如下: 说明:客户端发出一个http请求给web服务器,web服务器对http请求进 ...
- 手写一个简单版的SpringMVC
一 写在前面 这是自己实现一个简单的具有SpringMVC功能的小Demo,主要实现效果是; 自己定义的实现效果是通过浏览器地址传一个name参数,打印“my name is”+name参数.不使用S ...
- PhantomJS实现最简单的模拟登录方案
以前写爬虫,遇到需要登录的页面,一般都是通过chrome的检查元素,查看登录需要的参数和加密方法,如果网站的加密非常复杂,例如登录qq的,就会很蛋疼 在后面,有了Pyv8,就可以把加密的js文件扔给它 ...
- telnet简单操作 模拟请求
telnet简单操作 模拟请求 一: 二: 三: 按照以上操作即可!
- 简单MVC理解与实现
MVC基本概念 MVC大家不陌生,包含模型(Model).视图(View).控制器(Controller),其中模型用于基本业务逻辑的实现,视图用于响应结果的表示,控制器用于模型控制和请求分派.先放上 ...
- [模拟回调] demo1模拟用字符串调用js函数 demo2模拟springmvc controller回调页面js函数
demo1. 模拟用字符串调用js 函数 function dataQuery() { var strFun = "testCallBack"; var strParam = &q ...
- I.MX6 简单电路模拟USB设备的插入
/**************************************************************************** * I.MX6 简单电路模拟USB设备的插入 ...
- C++动态数组简单的模拟二元堆
//C++动态数组简单的模拟二元堆 #include<iostream> using namespace std; class BinaryHeap { private: int cap; ...
- 洛谷[Luogu] 普及村-简单的模拟总结
题目列表 注明:Level值代表在本难度下的排行.(纯粹本蒟蒻主观评判)注明:Level值代表在本难度下的排行.(纯粹本蒟蒻主观评判)注明:Level值代表在本难度下的排行.(纯粹本蒟蒻主观评判) P ...
- 简单mvc框架核心笔记
简单mvc框架核心笔记 看了thinkphp5的源码,模仿写了一个简单的框架,有一些心得笔记,记录一下 1.目录结构 比较简单,没有tp那么复杂,只是把需要的核心类写了一些. 核心类库放在mykj里, ...
随机推荐
- 莫烦TensorFlow_10 过拟合
import tensorflow as tf from sklearn.datasets import load_digits from sklearn.cross_validation impor ...
- 【使用篇二】SpringBoot服务端数据校验(8)
对于任何一个应用而言,客户端做的数据有效性验证都不是安全有效的,而数据验证又是一个企业级项目架构上最为基础的功能模块,这时候就要求我们在服务端接收到数据的时候也对数据的有效性进行验证.为什么这么说呢? ...
- 了解html表单
html表单 表单的根标签:form form标签属性 action:处理表单业务的后台代码的位置(URL) method:提交方式 post get 默认值 enctype:encode type ...
- isinstance 与 issubclass
isinstance与issubclass都是用于判断的,有什么区别呢? 1. isinstance字面意思:实列, 用户判断对象所属类型,包含类的继承关系. 2. issubclass字面理解:是子 ...
- appium--解决中文输入不了的问题
配置 from appium import webdriver desired_caps={} desired_caps['platformName']='Android' #模拟器 desired_ ...
- cf 1182 E - Product Oriented Recurrence
当时脑残了, 不会写矩阵快速幂中更改的系数, 其实把他扔到矩阵里同时递推就好了 #include<cstdio> #include<algorithm> #include< ...
- 题解 P3620 【[APIO/CTSC 2007]数据备份】
直接贪心(每次选最小)的话显然不对...样例都过不了... 选两个办公楼的时候,显然不能跨越另一个楼,这样不优... 于是 先把原数列处理成n-1个的数(每一个办公楼和上一个的距离),存在a[]中 题 ...
- [LeetCode] 881. Boats to Save People 渡人的船
The i-th person has weight people[i], and each boat can carry a maximum weight of limit. Each boat c ...
- [LeetCode] 16. 3Sum Closest 最近三数之和
Given an array nums of n integers and an integer target, find three integers in nums such that the s ...
- presto整合hive
Presto安装 前提条件: hadoop安装好了(并启动了) + hive安装好了 文档网址:http://prestodb.jd.com/docs/current/install ...