Java 使用 com.jayway.jsonpath.JsonPath 的代码迁移错误

Java code migration error using com.jayway.jsonpath.JsonPath

我正在使用 Java 代码并在 ColdFusion 中转换代码。我遇到了一些挑战。这是我在 Java:

中的一个功能
import com.jayway.jsonpath.JsonPath;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONStyle;

private static String getDetails(String instaDetailsElement) {
   String jsonResponse = instaDetailsElement.split(" = ")[1];
   JSONArray mediaArray = JsonPath.read(jsonResponse, "$.entry_data.PostPage[:1].graphql.shortcode_media");
   String returnJsonString = mediaArray.toJSONString(new JSONStyle(JSONStyle.FLAG_IGNORE_NULL));
   System.out.println(returnJsonString);
   return returnJsonString;
}

这两行给我带来了一些麻烦:

var mediaArray = JsonPath.read(jsonResponse, "$.entry_data.PostPage[:1].graphql.shortcode_media");
var returnJsonString = mediaArray.toJSONString(new JSONStyle(JSONStyle.FLAG_IGNORE_NULL));

这是我到目前为止所做的尝试。我为 JSON 路径加载了 jar 库并尝试像这样使用它:

Application.cfc 设置

<cfset this.javaSettings = {LoadPaths = ["cfc/jar"], loadColdFusionClassPath = true, reloadOnChange = false}>

CF码:

public any function getDetails(String instaDetailsElement) {
        var jsonResponse = instaDetailsElement.split(" = ")[1];
        var JsonPath = Createobject("java","com.jayway.jsonpath.JsonPath");
        writedump(application);
        var mediaArray = JsonPath.read(jsonResponse, "$.entry_data.PostPage[:1].graphql.shortcode_media");
        writedump(mediaArray); abort;
        var returnJsonString = mediaArray.toJSONString(new JSONStyle(JSONStyle.FLAG_IGNORE_NULL));
        return returnJsonString;
    }

当我转储 JsonPath 对象 (screen shot) 时,我能够查看 class 方法,但是当我尝试调用 JsonPath.read() 时,我收到此错误:

No matching Method for read(string, string) found for com.jayway.jsonpath.JsonPath

TL;DR;

No matching method for read(string, string) found for com.jayway.jsonpath.JsonPath

从技术上讲,错误消息是正确的:没有接受两个字符串的 read() 方法(尽管 java 代码中就是这样使用的)。该方法实际上需要 三个 个参数:

为第三个参数传入一个空数组:

JsonPath.read(jsonResponse, "$.entry_data.PostPage[:1].graphql.shortcode_media", []);

解释:

String jsonResponse = instaDetailsElement.split(" = ")[1];
JsonPath.read(jsonResponse, "$.entry_data.PostPage[:1].graphql.shortcode_media")

如果真的没有 read(String, String) 方法,您可能想知道为什么 java 代码完全有效,因为这正是它所使用的。它的工作是由于 java.

的一个特殊功能

documentation显示重载的read(..)方法实际上有三个个参数,但其中一个比较特殊:

read(String json,
     String jsonPath,
     Predicate... filters)

注意到 class 名称(谓词)后的 ... 了吗?这是一个名为 "varargs" 的构造(或可变数量的参数):

You can use a construct called varargs to pass an arbitrary number of values to a method. You use varargs when you don't know how many of a particular type of argument will be passed to the method. It's a shortcut to creating an array manually ...

To use varargs, you follow the type of the last parameter by an ellipsis (three dots, ...), then a space, and the parameter name. The method can then be called with any number of that parameter, including none.

因此在 java 中,您可以完全省略第三个参数并使用两个字符串调用 read(String, String)。 ColdFusion 不支持该语法,因为它会产生太多歧义。因此,代替省略参数,您可以传入一个空数组:

JsonPath.read(jsonResponse, "$.entry_data.PostPage[:1].graphql.shortcode_media", []);

(因为这在一个线程中变成了两个问题,为了清楚起见,我将第二个答案分开......)

var returnJsonString = mediaArray.toJSONString(new JSONStyle(JSONStyle.FLAG_IGNORE_NULL));

至于翻译JSONStyle代码,它有助于从内到外解压嵌套代码。然后分别处理每个部分:

  1. mediaArray.toJSONString(新的 JSONStyle(JSONStyle.FLAG_IGNORE_NULL));

  2. mediaArray.toJSONString( new JSONStyle( JSONStyle.FLAG_IGNORE_NULL ) )

  3. mediaArray.toJSONString( new JSONStyle( JSONStyle.FLAG_IGNORE_NULL ) )

片段 #1

使用名为 FLAG_IGNORE_NULLJSONStyle class 的静态 字段 。要访问该字段,请创建对该字段的引用 class:

JsonStyle = createObject("java", "net.minidev.json.JSONStyle");  
writeDump(JSONStyle.FLAG_IGNORE_NULL);

片段 #2

使用上面的静态字段创建 JSONStyle class 的全新 实例 。使用 createObject() 创建新实例,将静态字段传递给伪构造函数 init():

 newJsonStyle = createObject("java", "net.minidev.json.JSONStyle").init(JSONStyle.FLAG_IGNORE_NULL);
 writeDump( newJsonStyle );

片段#3

剩下的就是使用您刚刚创建的 JSONStyle 对象调用 JSONArray.toJSONString() 方法:

 result = mediaArray.toJSONString( newJsonStyle );
 writeDump(result);