3

我的 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,那将非常容易。

4

3 回答 3

9

您的网络服务返回的格式有它自己的名称HOCON(你可以在这里阅读更多关于它的信息)

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


将此 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值。所以你需要处理 type 的异常com.typesafe.config.ConfigException.Null


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

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

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

于 2019-10-08T16:22:26.093 回答
0

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

  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);
    }
}
于 2019-10-08T15:49:05.420 回答
0

好吧,这绝对不是这里给出的最佳答案,但有可能,至少……</p>

像这样操作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 ——&gt; could be done directly, of course
        dataMap.put(key, val);
    }

    // print the map content
    dataMap.forEach((key, value) -> System.out.println(key + " ——&gt; " + value));
}

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

于 2019-10-08T15:08:55.220 回答