在做网站开发的时候我们都会写一个控制器,控制器的作用就是接收客户端的请求,有时候为了控制访问入口的唯一性,方便我们监控用户访问的数据;最近在抽时间写一个底层转发控制器请求的工具,说通俗一点就是首先我定义一个抽象类或者接口A(实现类A就标识为控制器),然后定义很多继承或者实现了A类的类B(用户真正的Controller);
1.定义一个抽象类作为所有控制器的父类
package thread;
public abstract class A<T> {
public String[] getRequireParams() {
return new String[] {};
}
public String[] getOptionalParams() {
return new String[] {};
}
public abstract T fly(String param);
}
2.定义子类B
package thread;
public class B extends A<String>{
public String[] getRequireParams() {
return new String[] {"a","b"};
}
public String[] getOptionalParams() {
return new String[] {"c"};
}
@Override
public String fly(String param) {
return "B类被调用";
}
}
3.定义子类B1
package thread;
public class B1 extends A<String>{
@Override
public String fly(String param) {
return "B1类被调用";
}
}
4.定义统一接收用户请求的controller类,下面就使用main方法模拟控制器
package thread;
import org.apache.commons.lang3.StringUtils;
public class DataHandler{
public static void main(String[] args) {
try {
//模拟控制器接收到的请求类的url
String action = "thread.B";
// String action = "thread.B1";
Class clazz = Class.forName(action);
A obj = (A)clazz.newInstance();
//接口必填参数
String[] requiredParams = obj.getRequireParams();
System.out.println(StringUtils.join(requiredParams));
//接口可选参数
String[] optionalParams = obj.getOptionalParams();
System.out.println(StringUtils.join(optionalParams));
//调用接口的具体执行方法,并返回值
Object result = obj.fly("sd");
System.out.println(result);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5.执行结果是
ab
c
B类被调用
说明:第4步中是通过模拟我们从控制器中获取到的请求信息,从信息中解析出具体类的全路径,然后通过反射的方式获取实例对象,因为这些实例对象A类的子类,所以我们把他们统一强转成A对象,但是根据多态的原理我们知道他们指向内存中的实例还是原来的对象。