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. Docker底层原理(三)

    1. 我们运行:docker run hello-world 由于本地没有hello-world,所以会远程下载一个hello-world的镜像,并在容器内运行. 2. docker run干了什么?

  2. 微信小程序实现图片放大预览效果

    可以直接用微信程序自己的api很方便的实现 核心方法 wx.previewImage: 直接上代码, wxml: <!--pages/prewpicture/prew.wxml--> &l ...

  3. 【oracle】oracle11g安装失败 提示找不到文件,模板General_Purpose.dbc不存在

    先确定一下自己的安装包是不是一起解压的! 不是就重新解压,重新装. 是,剩下的我也不会

  4. <Random>382 380

    382. Linked List Random Node class Solution { ListNode node; Random random; /** @param head The link ...

  5. nginx配置代理时参数说明

  6. Appium入门指南 - 环境搭建和Case编写

    本文档将详细介绍如何搭建 Appium 的运行环境,以及如何编写一个简单的 UI 自动化测试用例.其中,也会穿插讲解一些 Appium 的基本知识.关于 Appium 的更多信息,大家可以查看官方文档 ...

  7. [NOI2014]动物园(KMP,字符串)

    半年前看这题还感觉很神仙,做不动(没看题解). 现在过来看发现……这tm就是一个sb题…… 首先题面已经提示我们用 KMP 了.那 KMP 究竟能干啥呢? 看 $num$ 的定义.发现对于前缀 $i$ ...

  8. Linux性能优化实战学习笔记:第三十六讲

    一.上节总结回顾 上一节,我们回顾了经典的 C10K 和 C1000K 问题.简单回顾一下,C10K 是指如何单机同时处理 1 万个请求(并发连接 1 万)的问题,而 C1000K 则是单机支持处理 ...

  9. [LeetCode] 390. Elimination Game 淘汰游戏

    There is a list of sorted integers from 1 to n. Starting from left to right, remove the first number ...

  10. Deepin (Linux Debian)使用日记

    (现在Deepin使用了debian的stable源,如果求新,推荐使用排行榜前三的Linux发行版——> Manjaro) 修复开启混合显卡驱动后,屏幕泛白偏灰问题“: https://blo ...