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. bugku love

    emmm....控制台运行一下 接着查一下是否有壳 显示是没有壳的,接着查看一下结构 也没有什么发现,上ida看一下吧,顺便说一句每个人的解题思路都不一样.面对一开始都不清楚的结构我会选择交叉引用这样 ...

  2. java虚拟机05(Java虚拟机的参数)

    原文在此 (1)-Xms20M 表示设置堆容量的最小值为20M,必须以M为单位 (2)-Xmx20M 表示设置堆容量的最大值为20M,必须以M为单位.将-Xmx和-Xms设置为一样可以避免堆自动扩展. ...

  3. vue的自定义

    自定义组件 组件是可以被复用的页面的零件,其实就是一个插件,只是在vue里叫组件 先看看别人的组件 vant element Mint iView 去试试上面的组件,都是有脚手架版和直接引入使用的版本 ...

  4. 移动端 三段式布局 (flex方式)

    分享一种平时用的三段式布局(flex) 主要思路是  上中下    header&footer 给高度  main 占其余部分 html 部分 <div class='wrap'> ...

  5. Spark的任务提交和执行流程概述

    1.概述 为了更好地理解调度,我们先看一下集群模式的Spark程序运行架构图,如上所示: 2.Spark中的基本概念 1.Application:表示你的程序 2.Driver:表示main函数,创建 ...

  6. UVA - 1451 Average (斜率优化)

    题意:由01组成的长度为n的子串,AT由0表示,GC由1表示,求一段长度大于等于L且GC率最高的子串的起始终止坐标,若GC率相同,取长度较小,若长度相同,取起始坐标最小. 分析: 1.一个子串(i+1 ...

  7. http 请求code状态码

    状态码 含义 100 客户端应当继续发送请求.这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝.客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应.服务器必须在 ...

  8. MySql索引原理分析

    面试 问:数据库中最常见的慢查询优化方式是什么? 同学A:加索引. 问:为什么加索引能优化慢查询?同学A:...不知道同学B:因为索引其实就是一种优化查询的数据结构,比如Mysql中的索引是用B+树实 ...

  9. 英语 - take的短语

    take care of  照顾 take place  发生 take action  行动 take over  接管 take in   欺骗(某人) take up   拿起 take awa ...

  10. 【OJ2216】小奇的数列

    题目大意 : 给定一个长度为 \(n\) 的数列,以及 \(m\) 次询问,每次给出三个数 \(l\),\(r\) 和 \(P\),询问 \((\sum_{i=l_1}^{r_1}a_i)\;mod\ ...