`
knight_black_bob
  • 浏览: 868229 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

手写 springmvc

阅读更多

 

 

手写 springmvc

代码下载 : demo 

 

 

 

结果测试:



 

 

项目结构

 

0.pom

 <properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version> 
		<org.slf4j-version>1.7.9</org.slf4j-version>
		<org.logback-version>1.0.1</org.logback-version>
		
	</properties>
	
  
  <dependencies>
   <!-- servlet 3.0 start -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		 <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<!-- servlet 3.0 end -->
		
		   <!-- loggger start -->
			<dependency>
				<groupId>org.slf4j</groupId>
				<artifactId>log4j-over-slf4j</artifactId>
				<version>${org.slf4j-version}</version>
			</dependency>

			<dependency>
				<groupId>org.slf4j</groupId>
				<artifactId>slf4j-api</artifactId>
				<version>${org.slf4j-version}</version>
			</dependency>
			<!-- loggger end -->
			
			
			<!-- json start -->
			<dependency>
				<groupId>com.alibaba</groupId>
				<artifactId>fastjson</artifactId>
				<version>1.2.8</version>
			</dependency>
			<!-- json end -->
			
  </dependencies>

  

 

1. AttributeParams  

@Target({ElementType.PARAMETER}) 
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface AttributeParams {
	String value() default ""; 
}

 

2.

@Target({ElementType.FIELD}) 
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface AutoWrite {
	String value() default ""; 
}

 

3.

@Target({ ElementType.TYPE }) 
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface Controller {
	String value() default ""; 
}

 

4.

@Target({ ElementType.METHOD,ElementType.PACKAGE,ElementType.TYPE }) 
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface RequestMapping {
	String value() default ""; 
}

 

5.

@Target({ ElementType.TYPE })  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface Service {
	String value() default ""; 
}

 

6.

@RequestMapping("/users")
@Controller
public class UserController {

	@AutoWrite
	private  UserService userService;
	 
	@RequestMapping("/user")
	public  User user(@AttributeParams("name") String name ){
		User user = userService.getUserByName(name);
		return user;
	} 
	
}

 

7.

public class User implements Serializable{

	private String name;
	private String pwd;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

}

 

8.

public interface UserService {

	public  User getUserByName(String name);

}

 

 

9.

@Service
public class UserServiceImpl implements UserService{

	@Override
	public User getUserByName(String name) {
		User user = new User();
		user.setName(name);
		user.setPwd(name +"123");
		return user;
	}

	 
}

 

 

10.

public class DispactherServlet extends HttpServlet{

	  
	private static final long serialVersionUID = 3077215544607397824L;

	private final Logger log = Logger.getLogger(DispactherServlet.class); 
	
	static List<String> packageNames = new ArrayList<String>();  
	static  Map<String, Object> instanceMapping = new ConcurrentHashMap<String, Object>(); 
	static  Map<String, ApplicationEntity> haddlerMapping = new ConcurrentHashMap<String, ApplicationEntity>(); 
	
	 @Override
	public void init() throws ServletException {
		 super.init();
		 String application = this.getInitParameter("contextConfigLocation");
		 //this.getServletContext().getClass().getResourceAsStream(application);
		 log.info("=== " +application);
	     String scanPackage="com.curiousby.baoyou.cn.showandshare.customized.mvc";
	     //1.获取扫描位置 
	     doScan(scanPackage); 
		 for (String packageName : packageNames) {
			 System.out.println(""+packageName);
		 }
		 
	     //2.实例化 service 和 controller
	     doInstances();
	     for (Entry<String,Object> entry : instanceMapping.entrySet()) {
			System.out.println(entry.getKey() +"    \t " + entry.getValue() );
		 }
	     
	     
	     //3. 建立映射关系 
	     doHaddlerMapping();
	     for (Entry<String,ApplicationEntity> entry : haddlerMapping.entrySet()) {
	    	 System.out.println(entry.getKey() +"    \t " + entry.getValue() );
		 }
	     
	     
	     //4.实现注入
	     doAop();
	     
	     //5.
	     
	     
	     
	 }
	 
	 private void doAop() { 
		 if (instanceMapping.size() <= 0 ) {
				return;
		 }
		 for (Map.Entry<String, Object> entry : instanceMapping.entrySet()) { 
			   Field[] declaredFields = entry.getValue().getClass().getDeclaredFields();
			   for (Field field : declaredFields) {
				   field.setAccessible(true);
				   if(field.isAnnotationPresent(AutoWrite.class)){
					   AutoWrite autoWrite = field.getAnnotation(AutoWrite.class);
					   String autoWriteName = autoWrite.value();
					   if(!UtilValidate.isNotEmpty(autoWrite.value())){
						   autoWriteName =field.getName();
					   }
					   autoWriteName = StringUtils.toLowerFirstString(autoWriteName);
					   field.setAccessible(true);
					   try {
						field.set(entry.getValue(), instanceMapping.get(autoWriteName));
						} catch (IllegalArgumentException e) {
							e.printStackTrace();
						} catch (IllegalAccessException e) {
							e.printStackTrace();
						}
				   }
			}
		 }
	 }

	private void doHaddlerMapping() {
		 if (instanceMapping.size() <= 0 ) {
				return;
		 }
		
		  for (Map.Entry<String, Object> entry : instanceMapping.entrySet()) {  
			  if (entry.getValue().getClass().isAnnotationPresent(Controller.class)) {
				  String baseUrl = "";
				  Controller controller = entry.getValue().getClass().getAnnotation(Controller.class);
				  
				 if(entry.getValue().getClass().isAnnotationPresent(RequestMapping.class)){
						RequestMapping requestMapping = (RequestMapping) entry.getValue().getClass().getAnnotation(RequestMapping.class);  
						baseUrl = requestMapping.value();
						
				 }
					
				  Method[] methods = entry.getValue().getClass().getMethods();  
				   for (Method method : methods) {
					   if (method.isAnnotationPresent(RequestMapping.class)) {  
						   RequestMapping methodRequestMapping = (RequestMapping) method.getAnnotation(RequestMapping.class);  
						   String url = baseUrl +  methodRequestMapping.value();
						   url = StringUtils.splitMultiPathToSimple("/"+url);
						   ApplicationEntity entity = new ApplicationEntity();
						   entity.method = method;
						   entity.controller = entry.getValue();  
						   haddlerMapping.put(url, entity);
						   
					   }else {  
	                       continue;  
	                   }  
				   }
			  }
		  }
	}

	private void doInstances() {
		if (packageNames.size() <= 0 ) {
			return;
		}
		
		for (String packageName : packageNames) {
			try {
				 Class<?> clazz = Class.forName(packageName.replace(".class", "").trim());  
				 String clazzName = clazz.getSimpleName();
				 
				if (clazz.isAnnotationPresent(Controller.class)) {
					Controller controller =  clazz.getAnnotation(Controller.class);
					if(UtilValidate.isNotEmpty(controller.value())){
						clazzName = controller.value();
					}
					Object newInstance = clazz.newInstance();
					clazzName = StringUtils.toLowerFirstString(clazzName);
					instanceMapping.put(clazzName, newInstance);
					
				}else if(clazz.isAnnotationPresent(Service.class)){
					Service service =  clazz.getAnnotation(Service.class);
					Class<?>[] interfaces = clazz.getInterfaces();
					if(UtilValidate.isNotEmpty(service.value())){
						clazzName = service.value();
					}else{
						for (Class<?> interfaceObj : interfaces) {
							clazzName = interfaceObj.getSimpleName();
							Object newInstance = clazz.newInstance();
							clazzName = StringUtils.toLowerFirstString(clazzName);
							instanceMapping.put(clazzName, newInstance);
						}
					}
					
					
					
					 
				}else{
					continue;
				}
			
				
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		
	}

	private void doScan(String scanPackage) {
		URL url = this.getClass().getClassLoader().getResource("/"+StringUtils.splitPathTransfer(scanPackage));
	    String path= url.getFile();
		for ( String file : new File(path).list()) {
	    	 File one = new File(path , file); 
	    	 if (one.isDirectory()) {
	    		 doScan(scanPackage +"."+ one.getName()); 
			 }else{
				 packageNames.add(scanPackage+"."+ one.getName());  
			 }
		}
		
	 }
	 
	 
	 

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doPost(req, resp);
	}
	 
	 
	 @Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException { 
	     RespEntity  result = new RespEntity();
	     String url = req.getRequestURI();  
	     String context = req.getContextPath();  
	     String path = url.replace(context, "").trim();  
	     ApplicationEntity entity = (ApplicationEntity) haddlerMapping.get(path);
         if(null == entity){
        	 result.setCode(RespEnums.RESP_ERROR_NOT_FOUND.getCode());
        	 result.setMsg(RespEnums.RESP_ERROR_NOT_FOUND.getDesc());
        	 result.setTimestamp(System.currentTimeMillis());
        	 out(resp, FastJsonUtils.toJSONString(result));
        	 return;
         }	     
	     List<Object> bulidParameters = bulidParameters(req,resp,entity);
	     try {
	    	 Object obj = entity.method.invoke( entity.controller,bulidParameters.toArray()  );
	    	 System.out.println(obj);  
	    	 result = new RespEntity(obj);
	    	 out(resp, FastJsonUtils.toJSONString(result));
        	 return;
	     } catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
	 
	 
	 private List<Object> bulidParameters(HttpServletRequest req,
			HttpServletResponse resp, ApplicationEntity entity) {
		 Parameter[] parameters = entity.method.getParameters();
		 List<Object> values = new ArrayList<Object>();
		 for (Parameter parameter : parameters) {
			if (parameter.getParameterizedType().getTypeName().equals("HttpServletRequest")) {
				values.add(req);
			}else if (parameter.getParameterizedType().getTypeName().equals("HttpServletResponse")) {
				values.add(resp);
			}else if(parameter.isAnnotationPresent(AttributeParams.class)){
				 String paramName = parameter.getAnnotation(AttributeParams.class).value();
				 if(!UtilValidate.isNotEmpty(paramName)){
					 paramName = parameter.getName();
				 }
				values.add(req.getParameter(paramName));
			}else{
				String paramName = parameter.getName();
				values.add(req.getParameter(paramName));
			}
		}
		 return values;
	}

	private void out(HttpServletResponse response, String str) {  
	        try {  
	            response.setContentType("application/json;charset=utf-8");  
	            response.getWriter().print(str);  
	        } catch (IOException e) {  
	            e.printStackTrace();  
	        }  
	 }  
}

 

 

 

 

 

 

 

 

 

 

 

 

 

捐助开发者 

在兴趣的驱动下,写一个免费的东西,有欣喜,也还有汗水,希望你喜欢我的作品,同时也能支持一下。 当然,有钱捧个钱场(支持支付宝和微信 以及扣扣群),没钱捧个人场,谢谢各位。

 

个人主页http://knight-black-bob.iteye.com/



 
 
 谢谢您的赞助,我会做的更好!

 

  • 大小: 24.2 KB
  • 大小: 21.7 KB
2
0
分享到:
评论

相关推荐

    基于PyTorchYOLOv4实现的口罩佩戴检测 自建口罩数据集分享.zip

    yolo

    基于java的ssm人事考勤签到管理系统(含LW+PPT+源码+系统演示视频+安装说明).7z

    系统采用了jsp技术,将所有模块采用以浏览器交互的模式,选择MySQL作为系统的数据库,开发工具选择Myeclipse来进行系统的设计。基本实现了人事管理系统应有的主要功能模块,本系统有管理员、员工与部门经理,管理员:个人中心、员工管理、部门经理管理、部门信息管理、员工考勤管理、签到管理、请假申请管理、工资查询管理、部门类型管理,部门经理;个人中心、员工管理、部门信息管理、员工考勤管理、签到管理、请假申请管理、工资查询管理,员工;个人中心、部门信息管理、员工考勤管理、签到管理、请假申请管理、工资查询管理等功能。 对系统进行测试后,改善了程序逻辑和代码。同时确保系统中所有的程序都能正常运行,所有的功能都能操作,本系统的开发获取人事管理系统信息能够更加方便快捷,同时也使人事管理系统信息变的更加系统化、有序化。系统界面较友好,易于操作。 关键词:人事管理系统;JSP技术 ;Mysql数据库;Java语言

    PyCharm 是一款功能强大且高度集成的 Python 开发环境,无论是用于简单的脚本编写,还是复杂的项目开发,都能提供高效、便捷的开发体验。对于 Python 开发者来说,它是一个非常值得推荐的工

    PyCharm 是一款功能强大且高度集成的 Python 开发环境,无论是用于简单的脚本编写,还是复杂的项目开发,都能提供高效、便捷的开发体验。对于 Python 开发者来说,它是一个非常值得推荐的工

    本科生毕业论文(设计)规范化管理和质量提升实施细则

    内容概要:本文旨在进一步规范本科生毕业论文(设计)的工作流程,明确各个环节的具体要求,确保毕业论文(设计)的质量。主要内容包括:毕业论文(设计)的目的和重要性、教务部和学院各自的管理职责、选题的原则和程序、指导教师的选择及职责、学生撰写的规范和要求、学术诚信的规定、答辩的具体流程和标准以及成绩评定的细则等方面。 适合人群:高校教务管理人员、计算机相关专业的师生及教育研究者。 使用场景及目标:该文件为本科院校提供了详细的论文(设计)管理指南,帮助建立科学、严格的评审机制,确保学生的学术成果真实有效,推动教学质量的全面提升。 其他说明:文中特别强调了对学术诚信的重视,所有毕业论文必须通过‘学术不端行为检测系统’和其他技术检测,并严格执行各项管理制度来保障论文的真实性和原创性。此外还鼓励创新,对于优秀的毕业作品给予了高度认可和支持措施。

    通过复合材料热压罐固化案例,以此来验证UMATHT和HETVAI子程序计算结果的一致性

    通过复合材料热压罐固化案例,以此来验证UMATHT和HETVAI子程序计算结果的一致性,具体细节可讨论

    tuned-profiles-oracle-2.16.0-1.el8.x64-86.rpm.tar.gz

    1、文件说明: Centos8操作系统tuned-profiles-oracle-2.16.0-1.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf tuned-profiles-oracle-2.16.0-1.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm

    Qt QPainter 重绘示例代码程序

    Qt QPainter 重绘示例代码程序

    串口快扫,用来快速扫描连接串口的设备

    经常使用串口设备的朋友都有一个烦恼,不知道设备使用的电脑上哪个串口号,通讯参数是多少。此软件专门为扫描串口参数而开发。解压密码:xiyue

    18.C语言程序设计--学生成绩管理系统.pdf

    18.C语言程序设计--学生成绩管理系统.pdf

    FingerprintJS

    此脚本用于在网页中加载 FingerprintJS v4 浏览器指纹库,使开发者能够通过 JavaScript 获取用户设备的唯一标识(指纹)。 指纹基于浏览器特征(如硬件信息、软件配置、网络参数等)生成,可用于: 用户追踪:匿名识别重复访问者 反欺诈检测:识别恶意机器人或虚假账号 安全验证:辅助多因素认证(MFA) 数据分析:统计设备分布特征

    软件工程研究生课程:移动互联网技术及应用的教学大纲解析

    内容概要:本文档是重庆大学针对软件工程专业开设的一门《移动互联网技术及应用》的详细教学大纲。课程分为多个模块,涵盖了移动互联网的现状和技术基础、不同应用场景及其商业模式、案例分析和实践操作。课程还关注于手机网站开发、应用程序构建及特定功能如GPS定位的应用等方面的技术,旨在培养学生的理论素养和技术实现能力,最终能够独立完成一个移动互联网创新项目。评分依据为出勤和课堂表现的过程评价与作品的实际效果实践评价相结合的方式。 适合人群:即将就读或者正在研读移动互联网相关专业的高校研究生,尤其是已掌握Web开发基础并有意深入探究移动互联网技术方向的学生。 使用场景及目标:此课程非常适合那些计划未来投身于快速发展的移动互联行业的年轻人;它不仅可以加深他们对该行业最新趋势的理解,还可以锻炼实际解决问题的能力。 其他说明:教学材料包括一系列权威性的书籍作为参考资料,帮助学员更广泛地获取知识。此外,通过一系列有针对性的设计任务和小组合作的学习形式进一步提高学生的综合技能水平。

    Dev-Cpp 5.9.2 TDM-GCC 4.8.1 Setup

    c++5.9.2

    前端分析-2023071100789s02

    前端分析-2023071100789s02

    大模型微调指南:使用DeePseek-R1进行特定领域专家模型训练与部署

    内容概要:本文详细介绍了如何将DeePseek-R1大模型微调为特定领域的专家系统,涵盖了从理论解释到实际操作的全流程。文章首先阐述了为何需要微调模型(如提升特定领域的专业知识和适应不同的任务需求、保证数据的安全性和节约成本),接着对比长文本处理、知识库利用及模型微调三种方法之间的差异,并深入讲解微调的基本流程(预训练模型的选择、数据集准备、超参数设置)。随后,针对非专业人士易入门的角度,文章示范了一个具体案例——如何用unsloth工具在Google Colab环境下构建一个微调版本的算命大师模型。文中还涉及微调后的模型测试比较及其后续部署至HuggingFace和Ollama平台的具体方法。 适合人群:具有基础编程能力并对自然语言处理感兴趣的研发人员和AI爱好者。 使用场景及目标:本文的目标读者可通过本指南学习并实践怎样根据自己所需的垂直领域(如金融、医学、心理咨询等领域),对现有的通用大模型进行针对性的优化和定制化训练;了解何时及为何应选用微调手段而不是直接采用标准模型或构建全新模型的方法来达成目的。

    GIT操作笔记以及用法

    GIT操作笔记以及用法

    高等教育本科毕业设计(论文)撰写的规范化指南及具体要求详解

    内容概要:本文档详细介绍了2022年度高等院校本科毕业设计(论文)的规范要求与写作要点。它涵盖了毕业设计的资料准备、内容要素的规定及格式布局等方面。从撰写结构的角度看,明确了包括题目、摘要、关键字的选择以及目录、引言乃至结论和参考资料等各个板块的作用和呈现方式。针对论文的格式化书写,强调了语言文字的精确运用、计量单位的标准执行,以及各类图表引用的具体做法。最后,在确保内容完整性和规范性的同时,鼓励学生展示创新能力。 适合人群:即将完成学业并需要撰写高质量论文以展现其专业水平及综合素质的本科毕业生及相关指导老师。 使用场景及目标:帮助在校生掌握正确的论文格式和撰写技巧,提升他们在毕业阶段的作品质量;同时也为企业招聘人才提供了一份衡量标准。 其他说明:文档中的指导方针不仅促进了学术诚信建设,而且推动了我国高教领域内的资源共享和交流互通。

    87.基于51单片机的电压表【正负5V,8255,ADC0808,扩展接线】(仿真).pdf

    87.基于51单片机的电压表【正负5V,8255,ADC0808,扩展接线】(仿真).pdf

    Delphi 12.3控件之初学.rar

    Delphi 12.3控件之初学.rar

    tuned-utils-systemtap-2.16.0-1.el8.x64-86.rpm.tar.gz

    1、文件说明: Centos8操作系统tuned-utils-systemtap-2.16.0-1.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf tuned-utils-systemtap-2.16.0-1.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm

Global site tag (gtag.js) - Google Analytics