【问题标题】:Convert HOCON string into Java object将 HOCON 字符串转换为 Java 对象
【发布时间】:2019-10-08 14:42:49
【问题描述】:

我的一个 web 服务返回下面的 Java 字符串:

[
  {
    id=5d93532e77490b00013d8862, 
    app=null,
    manufacturer=pearsonEducation, 
    bookUid=bookIsbn, 
    model=2019,
    firmware=[1.0], 
    bookName=devotional, 
    accountLinking=mandatory
  }
]

我有上述字符串的等效 Java 对象。我想将上面的 java 字符串类型转换或转换成 Java 对象。

我无法对它进行类型转换,因为它是一个字符串,而不是一个对象。所以,我试图将 Java 字符串转换为 JSON 字符串,然后我可以将该字符串写入 Java 对象,但没有运气得到 invalid character "=" 异常。

您可以更改 Web 服务以返回 JSON 吗?

这是不可能的。他们没有改变他们的合同。如果他们返回 JSON,那就太容易了。

【问题讨论】:

  • 它们的格式不清楚,所以我们可能希望字符串中有逗号。我们还有其他办法吗?
  • @f1sh 其实是标准格式。它叫HOCON

标签: java json parsing pojo hocon


【解决方案1】:

你的网络服务返回的格式有它自己的名字HOCON。 (您可以阅读更多关于它的信息here

不需要您的自定义解析器。不要试图重新发明轮子。 请改用现有的。


将此 maven 依赖项添加到您的项目中:

<dependency>
    <groupId>com.typesafe</groupId>
    <artifactId>config</artifactId>
    <version>1.3.0</version>
</dependency>

然后解析响应如下:

Config config = ConfigFactory.parseString(text);

String id = config.getString("id");
Long model = config.getLong("model");

还有一个选项可以将整个字符串解析成 POJO:

MyResponsePojo response = ConfigBeanFactory.create(config, MyResponsePojo.class);

不幸的是,这个解析器不允许null 值。所以你需要处理com.typesafe.config.ConfigException.Null类型的异常。


另一种选择是将HOCON 字符串转换为JSON

String hoconString = "...";
String jsonString = ConfigFactory.parseString(hoconString)
                                 .root()
                                 .render(ConfigRenderOptions.concise());

然后您可以使用任何 JSON-to-POJO 映射器。

【讨论】:

    【解决方案2】:

    嗯,这绝对不是最好的答案,但至少有可能……

    像这样以小步骤操作String,以获得可以处理的Map&lt;String, String&gt;。看这个例子,很基础:

    public static void main(String[] args) {
        String data = "[\r\n" 
                + "  {\r\n"
                + "    id=5d93532e77490b00013d8862, \r\n"
                + "    app=null,\r\n"
                + "    manufacturer=pearsonEducation, \r\n"
                + "    bookUid=bookIsbn, \r\n"
                + "    model=2019,\r\n"
                + "    firmware=[1.0], \r\n"
                + "    bookName=devotional, \r\n"
                + "    accountLinking=mandatory\r\n"
                + "  }\r\n"
                + "]";
    
        // manipulate the String in order to have
        String[] splitData = data
                // no leading and trailing [ ] - cut the first and last char
                .substring(1, data.length() - 1)
                // no linebreaks
                .replace("\n", "")
                // no windows linebreaks
                .replace("\r", "")
                // no opening curly brackets
                .replace("{", "")
                // and no closing curly brackets.
                .replace("}", "")
                // Then split it by comma
                .split(",");
    
        // create a map to store the keys and values
        Map<String, String> dataMap = new HashMap<>();
    
        // iterate the key-value pairs connected with '='
        for (String s : splitData) {
            // split them by the equality symbol
            String[] keyVal = s.trim().split("=");
            // then take the key
            String key = keyVal[0];
            // and the value
            String val = keyVal[1];
            // and store them in the map ——> could be done directly, of course
            dataMap.put(key, val);
        }
    
        // print the map content
        dataMap.forEach((key, value) -> System.out.println(key + " ——> " + value));
    }
    

    请注意,我刚刚复制了您的示例String,这可能导致了换行符,我认为仅将replace() 全部放在方括号中并不明智,因为firmware 的值似乎将它们作为内容包含在内。

    【讨论】:

      【解决方案3】:

      在我看来,我们将解析过程分为两步。

      1. 将输出数据格式化为 JSON。
      2. 通过 JSON utils 解析文本。

      在此演示代码中,我选择 regex 作为格式方法,并选择 fastjson 作为 JSON 工具。你可以选择杰克逊或gson。另外,我把[]去掉,你可以把它放回去,然后解析成数组。

      import com.alibaba.fastjson.JSON;
      import java.util.regex.Matcher;
      import java.util.regex.Pattern;
      
      public class SerializedObject {
          private String id;
          private String app;
      
          static Pattern compile = Pattern.compile("([a-zA-Z0-9.]+)");
          public static void main(String[] args) {
              String str =
                      "  {\n" +
                      "    id=5d93532e77490b00013d8862, \n" +
                      "    app=null,\n" +
                      "    manufacturer=pearsonEducation, \n" +
                      "    bookUid=bookIsbn, \n" +
                      "    model=2019,\n" +
                      "    firmware=[1.0], \n" +
                      "    bookName=devotional, \n" +
                      "    accountLinking=mandatory\n" +
                      "  }\n";
              String s1 = str.replaceAll("=", ":");
              StringBuffer sb = new StringBuffer();
              Matcher matcher = compile.matcher(s1);
              while (matcher.find()) {
                  matcher.appendReplacement(sb, "\"" + matcher.group(1) + "\"");
              }
              matcher.appendTail(sb);
              System.out.println(sb.toString());
      
              SerializedObject serializedObject = JSON.parseObject(sb.toString(), SerializedObject.class);
              System.out.println(serializedObject);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-08-30
        • 2015-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多