首页 > 解决方案 > 从可以采用多种形式并从 Java 中的 .properties 文件加载的字符串中提取值的最佳方法

问题描述

我有一个ws.properties文件,其中有一个名为success.code的属性,它为我提供了选择哪些 HTTP 状态成功代码 (2xx) 的选项,除了默认的 200 之外,我希望服务器也将其视为“成功” .

这个想法是这样的:

  1. 如果我输入这样的值:

success.code=201,202, 203(以逗号分隔的值)

负责提取这个值的那部分代码应该马上明白这是三个独立的代码,把每一个都提取出来,存储在一个列表或集合中,或者......

这实际上很容易:

private Set<String[]> getSuccessCodes(HashMap<String, String> codes){
    Set<String[]> successCodes = new HashSet<>();
    String value;
    for (Map.Entry<String, String> entry : codes.entrySet()) {
        value = entry.getValue();
        if(!StringUtils.isEmpty(value))
            successCodes.add(value.split("\\s*,\\s*"));
    }
    return successCodes;
}
  1. 这里有点复杂:

我还想添加这些选项:

success.code=[202, 220] (两个值写在钩子之间,用逗号分隔)

成功.code=2**

成功代码=[200, 205], 22*

因此,根据我为成功代码输入的值,程序应该能够理解要做什么以及从中返回什么。

这是可以实现的吗?

提前致谢

标签: javaproperties-file

解决方案


如果您不介意再添加三种方法,这里有一种方法:

  • "\\s*,\\s*(?![^\\[]*\\])"除非在括号中,否则使用在每个逗号处拆分您的 vlaues
  • 在结果数组上迭代/流并映射每个元素,检查它是否包含[*
  • 如果它包含使用其中的值[生成一个并将它们映射到它们的字符串值IntStream.rangeClosed(x,y)[x,y]
  • 如果它包含通过替换和*生成一个并将它们映射到它们的字符串值IntStream.rangeClosed(x00,x99)*09

就像是:

private static Set<String[]> getSuccessCodes(HashMap<String, String> codes){
    Set<String[]> successCodes = new HashSet<>();
    String value;
    for (Map.Entry<String, String> entry : codes.entrySet()) {
        value = entry.getValue();
        if(!StringUtils.isEmpty(value))
            successCodes.add(parse(value));
    }
    return successCodes;
}
public static String[] parse(String val) {
    String[] parts = val.split("\\s*,\\s*(?![^\\[]*\\])");
    return Arrays.stream(parts)
          .map(e -> e.contains("[")? getRangeCodes(e): e.contains("*")? getWildCCodes(e): e)
          .collect(Collectors.joining(",")).split("\\s*,\\s*");
}
private static String getRangeCodes(String e) {
    e = e.substring(1, e.length()-1);
    return IntStream.rangeClosed(Integer.parseInt(e.split("\\s*,\\s*")[0]), Integer.parseInt(e.split("\\s*,\\s*")[1]))
            .mapToObj(i -> String.valueOf(i))
            .collect(Collectors.joining(","));
}

private static String getWildCCodes(String e) {
    return IntStream.rangeClosed(Integer.parseInt(e.replace('*', '0')), Integer.parseInt(e.replace('*', '9')))
            .mapToObj(i -> String.valueOf(i))
            .collect(Collectors.joining(","));
}

经测试:

public static void main(String[] args) { 
    HashMap<String, String> codes = new HashMap<>();
    codes.put("foo", "201, 202, 203");
    codes.put("bar", "[202, 220]");
    codes.put("baz", "2**");
    codes.put("doo", "[200, 205], 22*");
    codes.put("woo", "200, 201, 202, 203,[209, 214], 29*");

    Set<String[]> set = getSuccessCodes(codes);
    set.forEach(s -> {System.out.println(Arrays.toString(s));});
}

推荐阅读