Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 解析REST服务的资源扩展_Java_Regex - Fatal编程技术网

Java 解析REST服务的资源扩展

Java 解析REST服务的资源扩展,java,regex,Java,Regex,我们正在尝试为REST服务构建资源扩展功能。可以通过以下模式提供资源扩展 fields=field1,field2(sf1,sf2),field3[Format],field4(sf1,sf2,sf3) 我应该使用正则表达式还是手动解析?在不知道每个字段的数据值的情况下,试图找出一个特定的正则表达式可能非常困难 为什么不使用POST或PUT并将数据值放入消息体中?这样,您就可以使用JSON来组织数据。(好的……XML或YAML也可以,但我喜欢JSON)。正则表达式不支持嵌套/平衡语法。例如,解析

我们正在尝试为REST服务构建资源扩展功能。可以通过以下模式提供资源扩展

fields=field1,field2(sf1,sf2),field3[Format],field4(sf1,sf2,sf3)
我应该使用正则表达式还是手动解析?

在不知道每个字段的数据值的情况下,试图找出一个特定的正则表达式可能非常困难


为什么不使用POST或PUT并将数据值放入消息体中?这样,您就可以使用JSON来组织数据。(好的……XML或YAML也可以,但我喜欢JSON)。

正则表达式不支持嵌套/平衡语法。例如,解析一条数学语句并确保每个开括号都有一个适当平衡的右括号,或者解析XML或HTML以确保每个元素都正确闭合,都需要更具表达力的语法。(有关学术解释,请特别注意常规语言和上下文无关语言之间的差异。)

为了用嵌套语法解析一种语言,你需要一个“下推自动机”(PDA)的等价物,但不用担心——所有这些花哨的术语实际上都很容易实现。您可以使用递归或循环来解决问题,在每次迭代中使用正则表达式,或者只构建自己的解析方法

我最近在Rest API中实现了完全相同的功能,虽然我的语法略有不同,但我怀疑您可能会发现以下代码很有用:

/**
 * Given a single packed string that defines a recursive set of fields,
 * this will parse and return a Map of terms from the root level where the
 * term is mapped to the packed string defining the sub-fields within that key.
 *  
 * Assume the primary/root result is a Movie...
 *              --(raw==null) get all movie First Order (FO) attributes
 * stars        --get all movie FO, and expand stars relation
 * title        --get movies FO id and title
 * title,stars  --get movies FO id and title, and expand stars relation
 * 
 * stars{}      --get all movie FO, and expand stars relation (same as stars)
 * stars{name}  --get all movie FO, and expand stars relation getting star FO id and name
 * stars{contractStudio}    --get all movie FO, expand stars relation getting all star FO and expand stars contract studio
 * stars{name,contractStudio}   --get all movie FO, and expand stars relation getting star FO id and name and expand stars contract studio
 * title,stars{name,contractStudio{name,founded}}   --get movies FO id and title, and expand stars relation getting star FO id and name and expand stars contract studio with the studio FO name and founded date
 */
private Map<String, String> parseRequestParameter(String raw) {
    if (raw == null || raw.isEmpty()) return Collections.emptyMap();
    Map<String, String> results = new HashMap<>();
    int i = 0;
    int j = 0;
    while (j < raw.length()) {
        char c = raw.charAt(j);
        //move j to end of attr name
        while (c != '{' && c != ',' && ++j < raw.length()) {c = raw.charAt(j);}
        String attr = raw.substring(i, i = j).trim();
        if (!attr.isEmpty()) {
            //capture the optional sub-expansion
            if (c == '{') {
                i++;  //move i past the opening '{'
                int pDepth = 1;
                while (pDepth > 0 && ++j < raw.length()) {  //pDepth is depth of nested { }
                    pDepth += (c = raw.charAt(j)) == '{' ? 1 : (c == '}' ? -1 : 0);
                }
                results.put(attr, raw.substring(i, j).trim());
                if (++j < raw.length()) c = raw.charAt(i = j);  //move i and c past the closing '}'
            }
            else {
                results.put(attr, null);
            }
        }
        //skip any unexpected suffix trash... only ',' marks next term.
        while ((i = ++j) < raw.length() && c != ',') {c = raw.charAt(j);}
    }
    return results;
}
/**
*给定一个定义递归字段集的压缩字符串,
*这将从根级别解析并返回术语映射,其中
*术语映射到定义该键内子字段的压缩字符串。
*  
*假设主/根结果是电影。。。
*--(raw==null)获取所有电影第一顺序(FO)属性
*明星——获取所有电影信息,扩大明星关系
*标题--获取电影的id和标题
*片名,明星——获取电影id和片名,并扩展明星关系
* 
*stars{}——获取所有电影FO,并扩展stars关系(与stars相同)
*stars{name}——获取所有电影的FO,并扩展stars关系以获取star FO id和name
*stars{contractStudio}——获取所有电影信息,扩展明星关系获取所有明星信息,并扩展明星合同工作室
*stars{name,contractStudio}——获取所有电影信息,并扩展stars关系获取star FO id和名称,并扩展stars contractStudio
*title,stars{name,contractStudio{name,founded}}--获取电影id和片名,并扩展stars关系获取star-FO-id和name,并使用工作室名称和创建日期扩展stars contract studio
*/
私有映射parseRequestParameter(字符串原始){
if(raw==null | | raw.isEmpty())返回Collections.emptyMap();
映射结果=新的HashMap();
int i=0;
int j=0;
而(j0&&++j
在我们的例子中,正如您可能从javadoc推断的那样,如果未指定扩展字符串,我们将返回结果的所有“一阶”(FO)属性。如果指定了特定属性,则它们要么是扩展项(如果它们命名了可扩展的关系属性),要么是缩小项(如果它们命名了FO属性)如果指定了任何缩小术语,则呈现的结果仅包含请求的术语。此外,无论请求的术语是什么,我们始终返回id

上述方法仅解析包含扩展规范的原始值。它生成一个映射,其中键是扩展规范顶层的单个项。这些值是扩展规范(剩余压缩)当它展开时,你需要应用到这个术语。这就是回归的作用。显然,这发生在比这个方法更高的层次上,我假设你可以从这里得到


此方法相当健壮。它假设原始值可能包含不平衡的大括号和垃圾字符。遇到这些字符时,它将忽略它们,并尽可能从原始值中恢复。这是一种“最后失败”的方法。

基本上这是我们正在遵循/构建的服务模型。这种模式将e在ACCEPT header中,我们将解析它。这些名称是Java字段名称,因此您可以假设Java允许命名字段的字符在这里适用。根据我的经验,在header中交易数据是不好的,特别是当您必须解析该信息时。但是如果必须这样做,请使用标准?标记来分隔查询段/字段ds.如果您不将自己限制在能够提供的数据范围内,并且如果有人(错误地或其他方式)传递逗号、括号或括号字符,则查询很容易中断。您好,我认为我的阐述不正确。这将不包含任何数据,这些字段只是元数据(如字段名称)。而且,它将只包含元数据。啊……那么您可以尝试使用它们来轻松构建cust
/**
 * Given a single packed string that defines a recursive set of fields,
 * this will parse and return a Map of terms from the root level where the
 * term is mapped to the packed string defining the sub-fields within that key.
 *  
 * Assume the primary/root result is a Movie...
 *              --(raw==null) get all movie First Order (FO) attributes
 * stars        --get all movie FO, and expand stars relation
 * title        --get movies FO id and title
 * title,stars  --get movies FO id and title, and expand stars relation
 * 
 * stars{}      --get all movie FO, and expand stars relation (same as stars)
 * stars{name}  --get all movie FO, and expand stars relation getting star FO id and name
 * stars{contractStudio}    --get all movie FO, expand stars relation getting all star FO and expand stars contract studio
 * stars{name,contractStudio}   --get all movie FO, and expand stars relation getting star FO id and name and expand stars contract studio
 * title,stars{name,contractStudio{name,founded}}   --get movies FO id and title, and expand stars relation getting star FO id and name and expand stars contract studio with the studio FO name and founded date
 */
private Map<String, String> parseRequestParameter(String raw) {
    if (raw == null || raw.isEmpty()) return Collections.emptyMap();
    Map<String, String> results = new HashMap<>();
    int i = 0;
    int j = 0;
    while (j < raw.length()) {
        char c = raw.charAt(j);
        //move j to end of attr name
        while (c != '{' && c != ',' && ++j < raw.length()) {c = raw.charAt(j);}
        String attr = raw.substring(i, i = j).trim();
        if (!attr.isEmpty()) {
            //capture the optional sub-expansion
            if (c == '{') {
                i++;  //move i past the opening '{'
                int pDepth = 1;
                while (pDepth > 0 && ++j < raw.length()) {  //pDepth is depth of nested { }
                    pDepth += (c = raw.charAt(j)) == '{' ? 1 : (c == '}' ? -1 : 0);
                }
                results.put(attr, raw.substring(i, j).trim());
                if (++j < raw.length()) c = raw.charAt(i = j);  //move i and c past the closing '}'
            }
            else {
                results.put(attr, null);
            }
        }
        //skip any unexpected suffix trash... only ',' marks next term.
        while ((i = ++j) < raw.length() && c != ',') {c = raw.charAt(j);}
    }
    return results;
}