JavaWeb之搭建自己的MVC框架(三)
1. 前言
在前两节的内容中,我们完成了一个基本的框架搭建。但是如果我们在前端请求中增加参数,我们要怎么传递到后台方法呢?接下来我们就来研讨这部分内容。
2. 实现
(1)首先我们增加一个新的注解ParamMapping,用来给方法的参数标注其对应的前端参数名称。
package com.mvc.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ParamMapping {
public String param() default "";
}
(2)我们在SayController中增加一个方法SayAnything,内容如下:
package com.mvc.controller; import com.mvc.annotation.ParamMapping;
import com.mvc.annotation.URLMapping; @URLMapping(url="/Say")
public class SayController{ @URLMapping(url="/Hello")
public String SayHello(){
System.out.println("Hello");
return "Hello";
} @URLMapping(url="/Hi")
public String SayHi(){
System.out.println("Hi");
return "Hi";
} @URLMapping(url="/Anything")
public String SayAnything(@ParamMapping(param="word") String word){
System.out.println(word);
return word;
}
}
在SayAnything的参数中,我们对String word参数进行了注解@ParamMapping(param="word"),表示将来前端传参数名word,我们的框架会将其对应到SayAnything的String word参数中。
(3)我们在SayController中增加一个方法SayAnything,内容如下:
package com.mvc.controller; import com.mvc.annotation.ParamMapping;
import com.mvc.annotation.URLMapping; @URLMapping(url="/Eat")
public class EatController { @URLMapping(url="/Apple")
public String EatApple(){
System.out.println("I'm eating apples");
return "Apple";
} @URLMapping(url="/Banana")
public String EatBanana(){
System.out.println("I'm eating Banana");
return "Banana";
} @URLMapping(url="/Anything")
public String EatAnything(@ParamMapping(param="fruit") String fruit,
@ParamMapping(param="cnt") Integer cnt) {
System.out.println("I'm eating "+fruit+", "+cnt);
return fruit;
}
}
EatAnything的参数的注解和SayAnything是同一个道理。
(4)调整ServletCenter,使其完成前端参数到JAVA后台参数的传递过程。
package com.mvc.servlet; import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mvc.annotation.ParamMapping;
import com.mvc.base.MVCBase;
import com.mvc.listener.UrlMappingCollection; public class ServletCenter extends HttpServlet {
private static final long serialVersionUID = -1163369749078348562L; private void doTransfer(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException, ClassNotFoundException,
SecurityException, NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException,
InstantiationException {
for (MVCBase mvcBase : UrlMappingCollection.getMvcBases()) {
if (req.getRequestURI().equals(
req.getServletContext().getContextPath()+mvcBase.getUrl())) {
Class<?> clazz = Class.forName(mvcBase.getController());
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.getName().equals(mvcBase.getMethod())) {
//拿到参数类型列表
Class<?>[] paramTypes = method.getParameterTypes();
//拿到参数的注解列表
Annotation[][] paramAnno = method.getParameterAnnotations();
//new一个参数值数组吗,将来调用方法的时候要用
Object[] paramValues = new Object[paramTypes.length];
//每个参数会形成paramAnno的第一维,每个参数的每个注解会行程paramAnno的第二维
//所以paramAnno.length和paramTypes.length是相等的。
for (int i=0; i<paramAnno.length; i++) {
for (int j=0; j<paramAnno[i].length; j++) {
if (paramAnno[i][j] instanceof ParamMapping) {
String paramName = ((ParamMapping) paramAnno[i][j]).param();
if (req.getParameter(paramName) != null) {
if (paramTypes[i].equals(String.class)) {
paramValues[i] = req.getParameter(paramName);
} else if (paramTypes[i].equals(Integer.class)) {
paramValues[i] = Integer.valueOf(
req.getParameter(paramName));
} else {
//其他类型待后续扩展
}
}
}
}
}
method.invoke(clazz.newInstance(), paramValues);
}
}
}
}
} @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try {
doTransfer(req, resp);
} catch (Exception e) {
System.out.println(e.toString());
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
try {
doTransfer(req, resp);
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
3. 测试效果:
启动tomcat,在浏览器中输入:
可以看到控制台打印出:
- 12345678
- I'm eating 1234, 2
JavaWeb之搭建自己的MVC框架(三)的更多相关文章
- JavaWeb之搭建自己的MVC框架(二)
1. 前言 在 JavaWeb之搭建自己的MVC框架(一) 中我们完成了URL到JAVA后台方法的最基本跳转.但是实际操作中会发现有一个不方便的地方,现在在com.mvc.controller包中只有 ...
- JavaWeb之搭建自己的MVC框架
https://blog.csdn.net/anita9999/article/details/83378111 自己写一个mvc框架吧(一) https://www.cnblogs.com/heba ...
- JavaWeb之搭建自己的MVC框架(一)
1. 介绍 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的 ...
- 从零开始实现一个简易的Java MVC框架(三)--实现IOC
Spring中的IOC IoC全称是Inversion of Control,就是控制反转,他其实不是spring独有的特性或者说也不是java的特性,他是一种设计思想.而DI(Dependency ...
- 使用PHP搭建自己的MVC框架
一.什么是MVC MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller ...
- IceMx.Mvc 我的js MVC 框架 三、动手来写一个评论模块儿
介绍 本人菜鸟,一些自己的浅薄见解,望各位大神指正. 本框架有以下优点 1.简单(调用简单.实现简单.不过度设计) 2.视图.控制器.模型分离(分离对于维护十分有必要) 3.组件化(每一个mvc模块儿 ...
- Spring MVC 框架的架包分析,功能作用,优点
由于刚搭建完一个MVC框架,决定分享一下我搭建过程中学习到的一些东西.我觉得不管你是个初级程序员还是高级程序员抑或是软件架构师,在学习和了解一个框架的时候,首先都应该知道的是这个框架的原理和与其有关j ...
- Java Servlet开发的轻量级MVC框架最佳实践
在Servlet开发的工程实践中,为了减少过多的业务Servlet编写,会采用构建公共Servlet的方式,通过反射来搭建轻量级的MVC框架,从而加快应用开发. 关于Servlet开发的基础知识,请看 ...
- spring mvc 框架搭建及详解
现 在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不 ...
随机推荐
- HiBench成长笔记——(9) 分析源码monitor.py
monitor.py 是主监控程序,将监控数据写入日志,并统计监控数据生成HTML统计展示页面: #!/usr/bin/env python2 # Licensed to the Apache Sof ...
- CentOS configuration uses the SFTP server
SFTP,即 SSH 文件传输协议( SSH File Transfer Protocol ),或者说是安全文件传输协议( Secure File Transfer Protocol ).SFTP 是 ...
- 在linux7(centos)中安装python3.7.2
一般情况下linux上都默认安装了python,检查一下我的版本 没有安装python3,但是目前已经是python3了,所以为了方便,还是要在系统上安装一下比较好. 上面的命令,直接输入python ...
- Linux系统测试工具
一.文件系统测试工具简介 1.LTP 参考网站:http://oss.sgi.com/projects/ltp/ LTP(Linux Test Project)是由SGI和IBM联合发起的项目,提供一 ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-question-sign
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- 关于cvPyrSegmentation(src, dst, storage, &comp, level, threshold1, threshold2)函数报错的问题解答
先挂上我写的代码: #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <highgui.h> #incl ...
- 用QEMU模拟运行uboot从SD卡启动Linux
平台:Qemu + vexpress-a9 u-boot:u-boot-2019.10 Linux:linux-4.14.13 之前介绍过用Qemu模拟运行uboot,然后从网络启动lin ...
- P1044 火星数字
P1044 火星数字 转跳点:
- --转载 详细介绍java中的数据结构
http://developer.51cto.com/art/201107/273003.htm 也许你已经熟练使用了java.util包里面的各种数据结构,但是我还是要说一说java版数据结构与算法 ...
- c++数据结构排序
#include<stdio.h> #include<stdlib.h> #include<time.h> typedef int ElemType; typede ...