有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

json将HOCON字符串转换为Java对象

我的一个Web服务返回以下Java字符串:

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

对于上面的字符串,我有一个等价的Java对象。我想将上面的java字符串类型转换成java对象

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

Can you change the web service to return JSON?

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


共 (3) 个答案

  1. # 1 楼答案

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

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

    在这个演示代码中,我选择regex作为格式化方法,选择fastjson作为JSON工具。你可以选择杰克逊或格森。此外,我删除了[{},您可以将其放回,然后将其解析到数组中

    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);
        }
    }
    
  2. # 2 楼答案

    嗯,这肯定不是这里给出的最佳答案,但这是可能的,至少

    通过像这样的小步操作String,以获得可以处理的Map<String, String>。看这个例子,它非常基本:

    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));
    }
    

    Please note that I just copied your example String which may have caused the line breaks and I think it is not smart to just replace() all square brackets because the value firmware seems to include those as content.

  3. # 3 楼答案

    web服务返回的格式有自己的名称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到POJO映射器