Open anjia0532 opened 5 months ago
@anjia0532 idea 很不错,之前也考虑过这个参数问题,现在的实现相对比较简单
因为json反序列化框架太多了,都兼容不太现实,要么类似 spring bean 那样,让用户自己配置反序列化类和方法。工具这块只是实现将用户贴入的json压缩(json min 化,去掉换行符,string字符串内的换行符替换成 \n ,将""替换成\"\")。好处简单替换下,可以格式化。开发人员阅读起来更方便。
要么是默认实现第一种,#p=new 类(),#p.方法(参数),......, 调用(#p)
这种实现起来更简单些,但是对于一些大类,没法格式化,肉眼看比较费事。
序列化框架查找当前工程中存在的 FastJson>JackJson>Gson
样例支持情况还挺多的,只要不是泛型(ognl 不支持泛型),基本是都没有问题,为了支持这个命令,arthas 插件反向支持了一个可以反向生产Clazz的JSON 字符串的命令。
code
@PostMapping("/userFastJson")
@ResponseBody
public Object userFastJson(@RequestBody User user) {
return user;
}
vmtool -x 3 --action getInstances --className com.wangji92.arthas.plugin.demo.controller.CommonController --express 'instances[0].userFastJson(@com.alibaba.fastjson.JSON@parseObject("{\"name\":\" \",\"age\":0}",@com.wangji92.arthas.plugin.demo.controller.User@class))' -c 2c95c2c2
code
@PostMapping("/userFastJson2")
@ResponseBody
public Object userFastJsonList(@RequestBody List<User> user) {
return user;
}
vmtool -x 3 --action getInstances --className com.wangji92.arthas.plugin.demo.controller.CommonController --express 'instances[0].userFastJsonList({@com.alibaba.fastjson.JSON@parseObject("{\"name\":\" \",\"age\":0}",@com.wangji92.arthas.plugin.demo.controller.User@class)})' -c 2c95c2c2
code
@PostMapping("/userFastJson3")
@ResponseBody
public Object userFastJsonArray(@RequestBody User[] user) {
return user;
}
vmtool -x 3 --action getInstances --className com.wangji92.arthas.plugin.demo.controller.CommonController --express 'instances[0].userFastJsonArray(new com.wangji92.arthas.plugin.demo.controller.User[]{@com.alibaba.fastjson.JSON@parseObject("{\"name\":\" \",\"age\":0}",@com.wangji92.arthas.plugin.demo.controller.User@class)})' -c 75d40b07
code
@PostMapping("/userFastJson4")
@ResponseBody
public Object userFastJsonArray(@RequestBody Map<String,User> user) {
return user;
}
arthas command
vmtool -x 3 --action getInstances --className com.wangji92.arthas.plugin.demo.controller.CommonController --express 'instances[0].userFastJsonArray(#{"_AR_": @com.alibaba.fastjson.JSON@parseObject("{\"name\":\" \",\"age\":0}",@com.wangji92.arthas.plugin.demo.controller.User@class)})' -c 75d40b07
基本上这个命令功能,基本上实现完毕,还有写小缺陷需要自测一下,就可以发布了
@anjia0532 你看看呢?
Set
@PostMapping("/userFastJson233")
@ResponseBody
public Object userFastJsonSet(@RequestBody Set<User> user) {
return user;
}
userFastJsonSet((#set=new java.util.HashSet(),#set.add(JSON解析的结果),#set)
vmtool -x 3 --action getInstances --className com.wangji92.arthas.plugin.demo.controller.CommonController --express 'instances[0].userFastJsonSet((#set=new java.util.HashSet(),#set.add(@com.alibaba.fastjson.JSON@parseObject("{\"name\":\"wnagji\",\"age\":0}",@com.wangji92.arthas.plugin.demo.controller.User@class)),#set))' -c 197a18de
奈斯
@anjia0532 你看看呢?
ognl 脚本里面不能出现 <>
符号
com.alibaba.fastjson.JSON#parseObject(java.lang.String, com.alibaba.fastjson.TypeReference<T>, com.alibaba.fastjson.parser.Feature...)
这种转换的方式不支持 ,只能为Clazz
尝试通过set 方法设置泛型的对象信息
由于最外层没有指定泛型,可能生成的Object 对象和实践对象对应的类型不匹配的,可能需要手动修改一下
/**
* 处理这种泛型复杂参数 TestGeneratesClazz<String,Map<String,User>> test
* 1、ognl 本身不支持泛型参数
* 2、通过Json 构建外层对象 TestGeneratesClazz
* 3、获取TestGeneratesClazz所有泛型参数
* 4、遍历TestGeneratesClazz 所有字段 包含了泛型参数 且非基本类型,通过判断是否有set方法进行赋值 同理赋值使用json 构造
* 5、构建脚本 差异化解决无法处理泛型的问题..
* @param param
* @return
*/
public Object testParam(TestGeneratesClazz<String,Map<String,User>> param) {
return param;
}
vmtool -x 3 --action getInstances --className com.wangji92.arthas.plugin.demo.controller.CommonController --express 'instances[0].testParam((#p=@com.alibaba.fastjson.JSON@parseObject("{\"user2\":{\"name\":\" \",\"age\":0},\"integer\":0,\"st\":\" \",\"user\":\" \",\"test\":{\"_key_\":{\"name\":\" \",\"age\":0}}}",@com.wangji92.arthas.plugin.demo.controller.TestGeneratesClazz@class),(#p.setUser(@com.alibaba.fastjson.JSON@parseObject("{\"user2\":{\"name\":\" \",\"age\":0},\"integer\":0,\"st\":\" \",\"user\":\" \",\"test\":{\"_key_\":{\"name\":\" \",\"age\":0}}}",@com.wangji92.arthas.plugin.demo.controller.TestGeneratesClazz@class))),(#p.setTest(@com.alibaba.fastjson.JSON@parseObject("{\"user2\":{\"name\":\" \",\"age\":0},\"integer\":0,\"st\":\" \",\"user\":\" \",\"test\":{\"_key_\":{\"name\":\" \",\"age\":0}}}",@com.wangji92.arthas.plugin.demo.controller.TestGeneratesClazz@class))),#p))' -c 6f54e410
https://www.json.cn/jsonzip/ 这个工具比较方便点
非广哈,如果不介意安装三方工具(而不是打开网页的话),我个人更推荐 https://u.tools/download/ 支持 win/mac/linux 。类似时间戳转换,json格式化,压缩,翻译,加解密等等有很丰富的插件。不用费劲收藏各类工具网站
@anjia0532 这个工具 我也有安装哈哈 OCR识别很爽
有个蛋疼的小tips,如果要用JSON序列化反序列化,注意检查下参数里有没有字段上加了 @JsonIgnore
和 @JSONField(serialze=false)
等注解。否则会出现反序列化不传值的问题。
有个蛋疼的小tips,如果要用JSON序列化反序列化,注意检查下参数里有没有字段上加了
@JsonIgnore
和@JSONField(serialze=false)
等注解。否则会出现反序列化不传值的问题。 这里干掉了..
嗯,我不是说插件会把本该忽略的字段带上,而是针对用户说的,在用的过程中,遇到死活传不进的值,看看有没有加这个注解。
嗯,我不是说插件会把本该忽略的字段带上,而是针对用户说的,在用的过程中,遇到死活传不进的值,看看有没有加这个注解。
这个是JSON 工具限制的 ~ 忽略了
@WangJi92 非广哈,新版的 arthas 的 json 序列化我体验了,但是感觉 Cool Request 的调用体验更好一些。
普通入参
对象入参
@anjia0532 这个侧重点不一样,这个http请求,我喜欢用官方 Idea HTTP Client ,arthas 这个是反向构造一个json 字符串,用来写文档之类的
以 Vmtool Get Instance Invoke Method Field 为例,对于简单的基础类型可以直接写,但是对于自定义类型则相对麻烦些。
插件默认给
vmtool -x 3 --action getInstances --className 类 --express 'instances[0].方法(new 类())' -c classload hash
OGNL 的方式
Json 的方式
我个人更喜欢用这种方式
是否考虑再简化下操作?比如自动生成全了。人工只填写参数就行了。