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框架(三)的更多相关文章

  1. JavaWeb之搭建自己的MVC框架(二)

    1. 前言 在 JavaWeb之搭建自己的MVC框架(一) 中我们完成了URL到JAVA后台方法的最基本跳转.但是实际操作中会发现有一个不方便的地方,现在在com.mvc.controller包中只有 ...

  2. JavaWeb之搭建自己的MVC框架

    https://blog.csdn.net/anita9999/article/details/83378111 自己写一个mvc框架吧(一) https://www.cnblogs.com/heba ...

  3. JavaWeb之搭建自己的MVC框架(一)

    1. 介绍 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的 ...

  4. 从零开始实现一个简易的Java MVC框架(三)--实现IOC

    Spring中的IOC IoC全称是Inversion of Control,就是控制反转,他其实不是spring独有的特性或者说也不是java的特性,他是一种设计思想.而DI(Dependency ...

  5. 使用PHP搭建自己的MVC框架

    一.什么是MVC MVC模式(Model-View-Controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller ...

  6. IceMx.Mvc 我的js MVC 框架 三、动手来写一个评论模块儿

    介绍 本人菜鸟,一些自己的浅薄见解,望各位大神指正. 本框架有以下优点 1.简单(调用简单.实现简单.不过度设计) 2.视图.控制器.模型分离(分离对于维护十分有必要) 3.组件化(每一个mvc模块儿 ...

  7. Spring MVC 框架的架包分析,功能作用,优点

    由于刚搭建完一个MVC框架,决定分享一下我搭建过程中学习到的一些东西.我觉得不管你是个初级程序员还是高级程序员抑或是软件架构师,在学习和了解一个框架的时候,首先都应该知道的是这个框架的原理和与其有关j ...

  8. Java Servlet开发的轻量级MVC框架最佳实践

    在Servlet开发的工程实践中,为了减少过多的业务Servlet编写,会采用构建公共Servlet的方式,通过反射来搭建轻量级的MVC框架,从而加快应用开发. 关于Servlet开发的基础知识,请看 ...

  9. spring mvc 框架搭建及详解

    现 在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不 ...

随机推荐

  1. MySQL学习之SQL基础(一)DDL

    Sql基础 DDL (data defination language) 创建表 CREATE TABLE emp( ename varchar(10), hiredate date, sal dec ...

  2. mysq8设置编码utf8

    设置mysql默认编码utf8 以及其他配置 系统:centos7 vi /etc/my.cnf #红色部分如果以存在则在他的下方添加 [mysql] default-character-set=ut ...

  3. 解题报告:luogu P2299

    题目链接:P2299 Mzc和体委的争夺战 单源最短路板子题吗,体面晦涩难懂(语文不好),以为是有向图,只有\(30pts\),其实是无向的,我使用了刚学来的\(SPFA\),通过了此题: \(Cod ...

  4. Project导入RedMine甘特图展示

    前端时间因公司业务需要使用RedMine来管理项目进度. 但是使用其自带的csv导入工具无法完成导入. 而我是java开发,并不会所谓的ruby语言,自然无法在段时间内完成此导入功能的修改. so,经 ...

  5. 自己写个tween

    public Vector3 begin,end;//起始终止坐标 public float BtoE_time;//用时 float timer,lerp;//计时器和进度值 void Update ...

  6. 注解方式实例化Java类

    context:component-scan标签: Sprng容器通过context:component-scan标签扫描其base-package标签属性值指定的包及其子包内的所有的类并实例化被@C ...

  7. Windows和Ubuntu双系统时钟同步的方法。

    参考文章 https://blog.csdn.net/zyqblog/article/details/79318955 电脑安装Ubuntu和Windows双系统以后,每次Ubuntu时间和时区设了以 ...

  8. 082-PHP的do-while循环break跳出

    <?php $i = 1; do { echo $i; $i = $i + 1; if ($i >= 5) { echo "break<br>"; brea ...

  9. Python 比较 相等性 真值

    1 == 操作符测试 值 的相等性: is 测试对象的一致性.注意短字符串的is相等性测试,PVM会缓存短字符串,s1 is s2 将返回true. 2 false:"", [], ...

  10. HDU 4862 JUMP 最小费用最大流

    2014 多校的B题,由于我不怎么搞图论,当时碰到这个题目,我怎么想都没往网络流方面弄,不过网络流真的是个好东西,对于状态多变,无法用动规或者数据结构来很好表示的时候,非常有用 这个题目要求每个点一定 ...