[BUG]ValueFilter过滤对于json字符串发现没有进入apply方法,没法生效
问题描述
简要描述您碰到的问题。 ValueFilter过滤对于json字符串发现没有进入apply方法,没法生效
环境信息
请填写以下信息:
- OS信息: [e.g.:CentOS 8.4.2105 4Core 3.10GHz 16 GB]
- JDK信息: [e.g.:Openjdk 1.8.0_312]
- 版本信息:[e.g.:Fastjson2 2.x.x]
重现步骤
如何操作可以重现该问题:
类似代码如下
String str =
"{\"num\":\"18005509635\",\"fee\":\"2000\"}";
JSON.toJSONString(str, new Filter())
public class Filter implements ValueFilter {
@Override
public Object apply(Object object, String name, Object value) {
return ["num"].containsKey(name.toUpperCase(Locale.ENGLISH)) ? "****" : value;
}
}
期待的正确结果
对您期望发生的结果进行清晰简洁的描述。 "{"num":"****","fee":"2000"}"
但是实际上还是输出原有的值"{"num":"18005509635","fee":"2000"}" 有点奇怪
我需要将 JSON.toJSONString(JSON.parseObject(str), new Filter()) 才可以输出期待结果
相关日志输出
请复制并粘贴任何相关的日志输出。
附加信息
如果你还有其他需要提供的信息,可以在这里填写(可以提供截图、视频等)。
是要表达这个意思吗?
@Test
public void test() {
TestData testData = new TestData("18005509635", "2000");
JSON.toJSONString(testData, new Filter());
}
@Data
@AllArgsConstructor
public static class TestData {
private String num;
private String free;
}
public class Filter implements ValueFilter {
@Override
public Object apply(Object object, String name, Object value) {
……
}
}
@Test
public void test() {
String str = "{\"num\":\"18005509635\",\"fee\":\"2000\"}";
JSONObject jsonObject = JSON.parseObject(str);
String result = JSON.toJSONString(jsonObject, new Filter());
assertEquals("{\"num\":\"****\",\"fee\":\"2000\"}", result);
}
public class Filter implements ValueFilter {
@Override
public Object apply(Object object, String name, Object value) {
return Collections.singleton("num").contains(name.toLowerCase(Locale.ENGLISH)) ? "****" : value;
}
}
测试过,ValueFilter可以起作用的啊
@wenshao 其实我直接JSON.toJSONString(str, new Filter()) 这种情况不行 如果JSON.paraseObject是可以的 因为我的场景是一个大串的JSON字符串 字符串又存在子对象的形式 只做一层paraseObject 还是没法进行第二层字对象的匿名化
@wenshao 其实我直接JSON.toJSONString(str, new Filter()) 这种情况不行 如果JSON.paraseObject是可以的 因为我的场景是一个大串的JSON字符串 字符串又存在子对象的形式 只做一层paraseObject 还是没法进行第二层字对象的匿名化
可以JSON.toJSONString(JSON.parseObject(str, str对应的原始javabean.class), new Filter()),如果直接JSON.parseObject(str),框架无法得知字符串的原始类型
@jujn 这种应该也点难搞 因为基于切面的实现 所有的bean都抽象成object 没法指定对应的bean类型来着
@Vetich 您可以发一下json结构,也许有其他方式实现您的效果。因为您提供的例子,ValueFilter是起作用的
@Test
public void test() {
String str = "{\"num\":\"18005509635\",\"fee\":\"2000\",\"children\":[{\"num\":\"12\",\"fee\":\"1\"}]}";
JSONObject jsonObject = JSON.parseObject(str);
String result = JSON.toJSONString(jsonObject, new Filter());
assertEquals("{\"num\":\"****\",\"fee\":\"2000\",\"children\":[{\"num\":\"****\",\"fee\":\"1\"}]}", result);
}
public class Filter implements ValueFilter {
@Override
public Object apply(Object object, String name, Object value) {
return Collections.singleton("num").contains(name.toLowerCase(Locale.ENGLISH)) ? "****" : value;
}
}
我也遇到一样的需求,我查看了源代码,发现从对象转换为json字符串,可以使用 ValueFilter并生效,但是如果是json 字符串转换为 Java 对象,不支持 ValueFilter。在源码中我发现 readFilter 并没有支持 ValueFilter。JSONReader 如下源码所示,只处理了 AutoTypeBeforeHandler 和 ExtraProcessor,但是 JSONWriter 中处理了 ValueFilter 。
我跟踪了源码,发现 json 字符转换为 Object,使用了 DynamicClassLoader,这块比较复杂,想改源代码也不知道从何下手。
官方能否增加对 Reader 支持 ValueFilter ?功能同 Writer,让开发者可以根据自己的需求处理 jsonField -> objectField。