Jayway JsonPath设置NOOPCache解决缓存旧值问题时报配置错误
问题产生原因
- 旧值返回问题:Jayway JsonPath默认开启全局静态缓存,会缓存编译后的路径表达式、内联函数(比如你用的
concat)的计算结果。你使用的路径完全固定,第一次执行后拼接结果就被存入静态缓存,后续传入不同的JSON对象时,框架直接返回缓存中的第一次计算结果,不会重新执行拼接逻辑。 - NOOPCache配置报错问题:JsonPath的缓存实例在类加载阶段就会完成初始化,且要求缓存提供者必须在第一次访问缓存(也就是第一次调用任何JsonPath读写方法)之前完成配置。如果你在已经执行过
JsonPath.read()触发缓存访问后,再调用CacheProvider.setCache()替换缓存实现,就会抛出Cache provider must be configured before cache is accessed.的错误。
正确解决方法
你可以根据业务场景二选一:
- 全局关闭缓存
将NOOPCache的配置逻辑放到应用启动的最早期执行(比如类静态初始化块、Spring容器启动前的配置类、main方法最开头),保证配置逻辑在所有JsonPath相关调用之前执行,示例:import com.jayway.jsonpath.spi.cache.CacheProvider; import com.jayway.jsonpath.spi.cache.NOOPCache; // 应用启动阶段最先执行 public class JsonPathConfig { static { CacheProvider.setCache(new NOOPCache()); } } // 后续业务代码正常调用即可,不会再返回缓存旧值 public String getFullName(String dynamicResponseJson) { String concatPath = "$.concat($.clientservice.output.client.lgivname, \", \" ,$.clientservice.output.client.lsurname)"; return JsonPath.read(dynamicResponseJson, concatPath); } - 单次调用临时关闭缓存(不修改全局配置)
如果不想影响项目中其他依赖默认缓存的JsonPath逻辑,可以在执行读取时单独传入关闭缓存的配置,仅当前次解析不使用缓存,示例:import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.Option; public String getFullName(String dynamicResponseJson) { String concatPath = "$.concat($.clientservice.output.client.lgivname, \", \" ,$.clientservice.output.client.lsurname)"; // 构建禁用缓存的独立配置 Configuration disableCacheConf = Configuration.builder() .options(Option.DISABLE_CACHE) .build(); // 用独立配置执行解析,不会命中全局缓存 return JsonPath.using(disableCacheConf) .parse(dynamicResponseJson) .read(concatPath); }
补充说明:如果对解析性能有要求,不使用全局缓存的场景下,可以提前将固定的JsonPath路径预编译为
JsonPath对象复用,避免每次解析重复编译路径带来的性能损耗。
内容的提问来源于stack exchange,提问作者S Gangal
相关产品推荐
相关产品推荐

