我正在调用一个传递JSON并返回JSON的Web服务。我正在尝试记录请求和响应以进行故障排除。我想排除或交叉(通过*)由字段名称正则表达式或其他东西标识的任何密码值。我正在使用Gson进行JSON解析和序列化。我在toJson
和logRequest
方法中加入了以下logResponse
方法调用:
private String toJson(String str) {
JsonElement elt = JSON_PARSER.parse(str);
return GSON.toJson(elt);
}
我没有看到任何可以帮助我JsonParser
对象的内容。我通过Gson
构建GsonBuilder
实例时尝试了各种方法但无济于事。这种方法的困难似乎是我没有映射到允许我使用ExclusionStrategy
的POJO。我目前的想法是递归检查JsonElement
我从parse
方法回来,但我不确定它会起作用并且感觉很笨重,所以我想我会问。
答案 0 :(得分:0)
由于通用JSON序列化的工作方式,以通用方式实现您的需求将变得困难。有人在这里问过类似的问题:Jackson: exclude object from serialization based on its properties。 在解析JSON字符串之后遍历JSON对象,识别密码字段并在序列化回记录器的字符串之前显式清理值可能是一个不错的选择,如果您更喜欢遵循此路径。
但是,如果您知道要记录的文档的json架构,则可以更轻松地解决问题。在这种情况下,您可以使用 jsonschema2pojo-maven-plugin
从架构生成Java Pojo对象,然后使用带有序列化排除策略的Gson
库。这是一个例子:
String jsonString = "{\"name\":\"parent\",\"id\":\"parentId\",\"password\":\"topsecret\"" +
",\"childPojo\":{\"name\":\"child\",\"id\":\"childId\",\"password\":\"topsecret\"}}";
RegexFieldExclusionStrategy strategy = new RegexFieldExclusionStrategy("pass.*");
Gson gson = new GsonBuilder()
.addSerializationExclusionStrategy(strategy)
.create();
MyPojo myPojo = gson.fromJson(jsonString, MyPojo.class);
String json = gson.toJson(myPojo);
System.out.println(json);
MyPojo 类:
public class MyPojo {
private String name;
private String id;
private String password;
private MyPojo childPojo;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public MyPojo getChildPojo() {
return childPojo;
}
public void setChildPojo(MyPojo childPojo) {
this.childPojo = childPojo;
}
}
请注意,Pojo
是一个手动实现,可以使用上面提到的插件替换为生成的实现,以简化整个过程。
RegexFieldExclusionStrategy 类:
import java.util.regex.Pattern;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
public class RegexFieldExclusionStrategy implements ExclusionStrategy {
private String regex;
public RegexFieldExclusionStrategy(String regex) {
Pattern.compile(regex);
this.regex = regex;
}
public boolean shouldSkipClass(Class<?> f) {
return false;
}
public boolean shouldSkipField(FieldAttributes f) {
return f.getName().toLowerCase().matches(regex);
}
}
程序将输出以下JSON文档:
{"name":"parent","id":"parentId","childPojo":{"name":"child","id":"childId"}}