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

最新文章

  1. Xamarin.Android之使用百度地图起始篇
  2. [Android] 环境配置之正式版Android Studio 1.0
  3. OpenSessionInview
  4. AEAI WM V1.0 工作管理系统开源发版
  5. OpenGL学习之路(二)
  6. MongoDB - The mongo Shell, Data Types in the mongo Shell
  7. Virtualbox安装增强工具失败
  8. GL应用方面
  9. java设计模式之桥接模式
  10. ssh连接虚拟机失败解决办法
  11. loadrunner 参数存储在data.ws、paralist、globals.h 中区别(参数与变量额区别于使用)
  12. Java开源生鲜电商平台-监控模块的设计与架构(源码可下载)
  13. java字符串应用之字符串编码转换
  14. 2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest
  15. Django--权限信息操作
  16. STM32 F4 DAC DMA Waveform Generator
  17. Solidworks如何打开swb文件
  18. 认识与学习shell
  19. centos 升级linux内核
  20. Retrofit2+Rxjava+MVP实践

热门文章

  1. 第2节 网站点击流项目(下):7、hive的级联求和
  2. 从植发AI看智能手术机器人的国产化之路
  3. node - 处理跨域 ( 两行代码解决 )
  4. Day4 - D - Watchcow POJ - 2230
  5. Python 使用 requests 模块发送请求的使用及封装
  6. 011.Delphi插件之QPlugins,延时加载服务
  7. UVA 12511/CSU 1120 virus 最长公共上升子序列
  8. GDOI#345. 送礼物「JSOI 2015」01分数规划+RMQ
  9. ES6与ES5的继承
  10. HDU 3397 线段树 双懒惰标记