目录
第一部分:预加载 得到文本中的那一行值,存放进map中预加载
一.前期准备:所要建的包和文本
二.com.gec.component
1.class JSONDispatcher
可以分为三部分
第一部分:预加载 得到文本中的那一行值,存放进map中预加载
1.功能
/**
* 预加载 得到文本中的那一行值,存放进map中预加载
* @return config <类名,类所在地址>
* @throws IOException
*/
// 预加载 得到文本中的那一行值,存放进map中
Map<String, String> loadConfig(){}2.步骤
// {1}获取类装载器
// {ps}类装载器有一个方法可以取得
// src / resources 下文件
// {2}获取输入流(handler.txt)// {4}创建 HashMap
// {4}包装为缓冲字符流(行读功能)
// 格式:UserHandler:com.gec.handlers.UserHandler
// {5}逐行读取, 解析数据。
// {6}用 : 号分割字符串
// {7}存入 map(key=data[0], val=data[1])
// {3}返回这个 map
第二部分:转化为handlers<类名,这个类创建的对象>
1.功能
/**
* 构造器 初始化 把config map中的数据<类名,类所在的地方>
* 转化为handlers<类名,这个类创建的对象>,供intercept使用
* @throws IOException
* @throws ClassNotFoundException
* @throws InstantiationException
*/
// 构造器 初始化 把map中的数据<类名,类所在的地方>转化为<类名,这个类创建的对象>
public JSONDispatcher2(){}2.步骤
// {1}声明与创建一个 Handler 容器 存放的内容:类名,创建的对象
// 以后 handler 则放置到这里。
private Map<String, Object> handler=new HashMap();// 构造器 初始化 把map中的数据<类名,类所在的地方>转化为<类名,这个类创建的对象>
public JSONDispatcher2(){// {1}加载配置 ..调用loadConfig()
// {2}获取map的Keyset
// {3}迭代 Map 数据
// {4}获取类的全限定名 (即value)。
// {5}根据 value 来加载字节码到 JVM
// {6}用字节码反射创建处理器对象
// (记住: 处理器必须提供无参构造器)// {6}存入 handlers (map容器)
}第三部分:执行方法
1.功能
/**
* 根据传入的数据,得到要执行的类名和方法名来执行方法
*/2.步骤
// {1}从 json 中获取 key为 "handler" 的数据
// 服务想知道客户端想调用哪个处理器。
// 得到:--->handlerName = UserHanlder or 其它Handler// {2}从 handlers(map)中根据类名得到 处理器 handlers(map)<类名,创建的对象>
// {3}从 json 中获取 key 为 method 的数据
// 服务想知道客户端想调用该处理器的什么方法 ?
// 想 "注册",还是 "登录", 还是想做什么 ?
// 这一步就是落实你要做什么 ?// {4}得到 处理器 的字节码对象
// {5}获取指定的方法对象
// 注意: 参数类型是 JSONObject// {6}打开方法调用权限
package com.gec.component;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.alibaba.fastjson.JSONObject;
/*
* JSONDispatcher
* 请求分发器(基于 JSON 数据格式的实现)
* 包含一个拦截客户请求的方法声明。
*/
public class JSONDispatcher implements RequestDispatcher<JSONObject> {
// {1}声明与创建一个 Handler 容器 存放的内容:类名,创建的对象
// 以后 handler 则放置到这里。
private Map<String, Object> handlers = new HashMap();
// 构造器 初始化 把map中的数据<类名,类所在的地方>转化为<类名,这个类创建的对象>
public JSONDispatcher() throws IOException, ClassNotFoundException, InstantiationException {
// {1}加载配置 ..调用loadConfig()
Map<String, String> config = loadConfig();
// {2}获取map的Keyset
Set<String> keySet = config.keySet();
// {3}迭代 Map 数据
for (String key : keySet) {
// {4}获取类的全限定名 (即value)。
String val = config.get(key);
// {5}根据 value 来加载字节码到 JVM
Class<?> clazz = Class.forName(val);
try {
// {6}用字节码反射创建处理器对象
// (记住: 处理器必须提供无参构造器)
Object handler = clazz.newInstance();
// {6}存入 handlers (map容器)
handlers.put(key, handler);
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// 预加载 得到文本中的那一行值,存放进map中
Map<String, String> loadConfig() throws IOException {
// {1}获取类装载器
ClassLoader loader = JSONDispatcher.class.getClassLoader();
// {ps}类装载器有一个方法可以取得
// src / resources 下文件
// {2}获取输入流(handler.txt)
InputStream is = loader.getResourceAsStream("handler.txt");
BufferedReader br = null;
// {4}创建 HashMap
Map<String, String> config = new HashMap();
try {
// {4}包装为缓冲字符流(行读功能)
br = new BufferedReader(new InputStreamReader(is));
// 格式:UserHandler:com.gec.handlers.UserHandler
String line = null;
// {5}逐行读取, 解析数据。
while ((line = br.readLine()) != null) {
// {6}用 : 号分割字符串
String[] data = line.split(":");
// {7}存入 map(key=data[0], val=data[1])
config.put(data[0], data[1]);
System.out.println(data[0] + ":" + data[1]);
}
} catch (IOException e) {
e.printStackTrace();
}
// {3}返回这个 map
return config;
}
@Override
public String intercept(JSONObject clientMsg) {
// {1}从 json 中获取 key为 "handler" 的数据
// 服务想知道客户端想调用哪个处理器。
// 得到:--->handlerName = UserHanlder or 其它Handler
String handlerName = clientMsg.getString("handler");
// {2}从 handlers(map)中根据类名得到 处理器 handlers(map)<类名,创建的对象>
Object handler = handlers.get(handlerName);
// {3}从 json 中获取 key 为 method 的数据
// 服务想知道客户端想调用该处理器的什么方法 ?
// 想 "注册",还是 "登录", 还是想做什么 ?
// 这一步就是落实你要做什么 ?
String mtdName = clientMsg.getString("method");
// {4}得到 处理器 的字节码对象
Class clazz = handler.getClass();
Method mtd = null;
String result = "";
try {
// {5}获取指定的方法对象
// 注意: 参数类型是 JSONObject
mtd = clazz.getDeclaredMethod(mtdName, JSONObject.class);
// {6}打开方法调用权限
mtd.setAccessible(true);
result = (String) mtd.invoke(handler, clientMsg);
} catch (IllegalArgumentException | IllegalAccessException | NoSuchMethodException e) {
// 对异常进行分类: NoSuchMethodException [我们的错]
// IllegalAccessException[我们的错]
// IllegalArgumentException[我们的错]
// 给我们来看, 不用上报。。
e.printStackTrace(); // 开发阶段可以测试的。。
} catch (InvocationTargetException e) {
e.printStackTrace(); // 开发阶段测试不出来。。
// --- 明天继续 ----
}
return result;
}
}
2.interface RequestDispatcher
package com.gec.component;
/*
* RequestDispatcher
* 请求分发器(接口)
* 包含一个拦截客户请求的方法声明。
* */
public interface RequestDispatcher <T> {
String intercept(T clientMsg);
}
三.com.gec.handlers
package com.gec.handlers;
import com.alibaba.fastjson.JSONObject;
public class UserHandler {
public UserHandler(){
System.out.println("创建了 UserHandler..");
}
public String register(JSONObject obj){
System.out.println(
"{UserHandler}调用 register..");
return "BJYXSZD!";
}
}
package com.gec.handlers;
import com.alibaba.fastjson.JSONObject;
public class AdminHandler {
public AdminHandler(){
System.out.println("创建了 AdminHandler..");
}
public String showList(JSONObject obj){
System.out.println(
"{AdminHandler}调用 showList..");
return null;
}
}
四.com.test.center
package com.test.center;
import java.io.IOException;
import java.sql.SQLException;
import org.junit.Test;
import com.alibaba.fastjson.JSONObject;
import com.gec.component.JSONDispatcher;
import com.gec.component.JSONDispatcher2;
import com.gec.domain.User;
import com.gec.exception.EntityException;
import com.gec.ui.UserConsole;
public class DisptacherCenter {
public JSONObject getTestData() {
JSONObject jsObj = new JSONObject();
//类似map
jsObj.put("handler", "UserHandler");
jsObj.put("method", "register");
// {
// "handler":"UserHandler", <---必须的(handler名字固定)
// "method":"register", <---必须的(method名字固定)
// "user":{ <---可变的
// "username":"kaikai",
// "password":"123",
// "age":"56",
// "sex":"男",
// ...省略...
// }
//
return jsObj;
}
// ------------------------[加载配置测试]----------------------------
@Test
public void testLoadConfig() { // 预加载
try {
JSONDispatcher disp = new JSONDispatcher();
JSONObject jsObj = getTestData();
String ret = disp.intercept( jsObj );
System.out.println("得到返回值: "+ ret);
System.out.println(jsObj);
} catch (Exception e) {
e.printStackTrace();
}
}
// public void testLoadConfig() { // 预加载
// try {
// JSONDispatcher2 disp = new JSONDispatcher2();
// JSONObject jsObj = getTestData();
// String ret = disp.intercept( jsObj );
// System.out.println("得到返回值: "+ ret);
// System.out.println(jsObj);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// ------------------------[----层]----------------------------
}
五.resources源文件夹
六.intercept执行流程图
intercept执行流程图