前言:
Json是一种轻量级的数据交换格式,易于机器解析与生成,并且可以有效提升网络传输的效率。
不论是服务器客户机模式中利用Socket传输参数。还是RMI的执行过程中,我们都会遇到参数的传输与转化的问题。当然,这里的参数可能是基本类型变量,也可能是某个类的对象。这里我们统一用参数来表达。
Socket支持各种方式的传输(字符串,字节流,对象等),当然本质上还是传输字节流。
在服务器/客户机收发参数时,我们可以将参数(一个或多个)转化为特定格式的、序列化的Json字符串用以进行网络发送。在对端解析此Json字符串取出所需要的一个或多个参数来处理后续的工作(例如:反射执行方法)。
我的代码用到了Gson来处理。
(Google公司发布的一个开放源代码的Java库,主要用途为序列化Java对象为JSON字符串,或反序列化JSON字符串成Java对象。)
代码:
public class ArgumentMaker {
private static final Gson gson = new GsonBuilder().create();//创建gson对象
private static final Type type = new TypeToken<Map<String, String>>(){}.getType();
//准备fromJson方法所需要的Type,即Map<String, String>的类型
private Map<String, String> argumentPool;
public ArgumentMaker() {
argumentPool = new HashMap<>();
}
public ArgumentMaker(String argString) {
argumentPool = gson.fromJson(argString, type);//这里是为了将参数集合的Json字符号串转化并存储到map中去
}
public static Gson getGson() {
return gson;
}
//通过相应的键找到对应参数的Json字符串再用fromJson方法获取参数
@SuppressWarnings("unchecked")
public <T> T getValue(String paraName, Class<?> paraType) {
String paraStr = this.argumentPool.get(paraName);
if(paraStr == null) {
return null;
}
return (T) gson.fromJson(paraStr, paraType);
}
@SuppressWarnings("unchecked")
public <T> T getValue(String paraName, Type paraType) {
String paraStr = this.argumentPool.get(paraName);
if(paraStr == null) {
return null;
}
return (T) gson.fromJson(paraStr, paraType);
}
//添加map元素
public ArgumentMaker addArgument(String name, Object value) {
this.argumentPool.put(name, gson.toJson(value));
return this;
}
//提供获取整个map的Json字符串的方法
@Override
public String toString() {
return gson.toJson(argumentPool);
}
}
工具的注意事项:
1、提供了将多个参数打包为一个集合并转化为Json字符串的方法(覆盖的toString方法),并且可以将这类集合的Json字符串解析存储到map,用以反解析获得参数(getvalue方法)。
2、map的键是某个参数的唯一标识,值为某个参数的Json字符串。如果在服务器与客户机的通信中利用这个工具去发送或解析的时候,双方必须统一键的格式(如下面的test中所写),才能准确地转化出对应的参数。
测试:
public class TestForArgumentMaker {
public static void main(String[] args) {
int a = 19;
String str = "string";
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "111");
map.put(2, "222");
StuInfo info = new StuInfo("张三", "20202020", false);
ArgumentMaker am1 = new ArgumentMaker().addArgument("arg0", a)
.addArgument("arg1", str)
.addArgument("arg2", map)
.addArgument("arg3", info);
System.out.println(am1.toString());
System.out.println("---------------分割线----------------");
ArgumentMaker am2 = new ArgumentMaker(am1.toString());
Object arg0 = am2.getValue("arg0", int.class);
Object arg1 = am2.getValue("arg1", String.class);
Object arg2 = am2.getValue("arg2", HashMap.class);
Object arg3 = am2.getValue("arg3", StuInfo.class);
System.out.println("参数类型: " + arg0.getClass().getName() + ", 参数值" + arg0);
System.out.println("参数类型: " + arg1.getClass().getName() + ", 参数值" + arg1);
System.out.println("参数类型: " + arg2.getClass().getName() + ", 参数值" + arg2);
System.out.println("参数类型: " + arg3.getClass().getName() + ", 参数值" + arg3);
}
}
下面是测试结果:
后面的一些工程会有对这个工具的使用。