通常要使用 Jackson 库解析 JSON,您可以使用ObjectMapper
像这样的类:
public static void main(final String[] args) {
final String json = "some JSON string";
final ObjectMapper mapper = new ObjectMapper();
final TestSuite readValue = mapper.readValue(json, TestSuite.class);
//Then some code that uses the readValue.
//Keep in mind that the mapper.readValue() method does throw some exceptions
//So you'll need to handle those too.
}
但是,我编写了一个快速测试类来检查 JSON 的解析,并遇到了一些问题。
基本上,JSON 的设计和域的设计不匹配。因此,您可以更改 JSON,也可以更改域对象。
更改 JSON 以适应域
- 包含“-”的属性名称在 Jackson 中无法很好地解析,因此需要将其删除。
- 在每个对象之前添加类名是没有帮助的。 Jackson 希望这些是属性,因此类名称需要删除或替换为属性名称。
- 必须提供域对象中的属性名称,以便 Jackson 解析它们。你不能只说这是一个对象,然后启动一个列表,该列表必须有一个属性名称/
在我调整 JSON 中的这些内容后,我用提供的域对象来解析它。我最终得到的 JSON 如下所示:
{
"testSuiteInfo":{
"description":"parse"
},
"listOfTestCases":{
"testCaseData":[
{
"sequence":"sequential",
"testNumber":"2",
"testCaseFile":"testcase\\Web\\Ab.xml"
},
{
"sequence":"sequential",
"testNumber":"3",
"testCaseFile":"testcase\\Web\\BC.xml"
}
]
}
}
这是我的测试方法,它确实解析了上面修改过的 JSON(请忽略所有转义字符)
public static void main(final String[] args) {
final String json = "{\"testSuiteInfo\":{\"description\":\"parse\"}," +
"\"listOfTestCases\":{" +
"\"testCaseData\":[" +
"{\"sequence\":\"sequential\",\"testNumber\":\"2\",\"testCaseFile\":\"testcase\\\\Web\\\\Ab.xml\"}," +
"{\"sequence\":\"sequential\",\"testNumber\":\"3\",\"testCaseFile\":\"testcase\\\\Web\\\\BC.xml\"}" +
"]" +
"}" +
"}";
final ObjectMapper mapper = new ObjectMapper();
try {
final TestSuite readValue = mapper.readValue(json, TestSuite.class);
System.out.println(readValue.getListOfTestCases()); //just a test to see if the object is built
}
catch (final Exception e) {
e.printStackTrace();
}
}
更改域以适合 JSON
首先,主要问题是将类名作为属性标识符。这使得以通常的方式处理这个 JSON 变得非常困难。我必须添加几个包装类来绕过 JSON 中的类名。
我添加了一个OverallWrapper
类有一个TestSuite
属性来满足 JSON 中的 TestSuite 类名称。
我还添加了一个TestCaseDataWrapper
类以满足 JSON 列表中的 TestCaseData 类名称。
我将 TestCase 类全部删除,因为它刚刚成为其他类之一的属性。
然后为了使属性名称与对象匹配,我使用了@JsonProperty
注解。
以下是修改后的类,以及可运行并解析 JSON 的最终解析器测试方法。 (再次,请原谅 JSON 字符串中的所有转义字符)
import org.codehaus.jackson.annotate.JsonProperty;
public class OverallWrapper {
private TestSuite testSuite;
@JsonProperty("TestSuite")
public TestSuite getTestSuite() {
return this.testSuite;
}
public void setTestSuite(final TestSuite testSuite) {
this.testSuite = testSuite;
}
}
import java.util.List;
import org.codehaus.jackson.annotate.JsonProperty;
public class TestSuite {
private TestSuiteInfo testSuiteInfo;
private List<TestCaseDataWrapper> testCaseData;
@JsonProperty("TestCase")
public List<TestCaseDataWrapper> getTestCaseData() {
return this.testCaseData;
}
public void setTestCaseData(final List<TestCaseDataWrapper> testCaseData) {
this.testCaseData = testCaseData;
}
@JsonProperty("TestSuiteInfo")
public TestSuiteInfo getTestSuiteInfo() {
return this.testSuiteInfo;
}
public void setTestSuiteInfo(final TestSuiteInfo testSuiteInfo) {
this.testSuiteInfo = testSuiteInfo;
}
}
import org.codehaus.jackson.annotate.JsonProperty;
public class TestSuiteInfo {
private String description;
@JsonProperty("-description")
public String getDescription() {
return this.description;
}
public void setDescription(final String description) {
this.description = description;
}
}
import org.codehaus.jackson.annotate.JsonProperty;
public class TestCaseDataWrapper {
@JsonProperty("TestCaseData")
private TestCaseData testcaseData;
public TestCaseData getTestcaseData() {
return this.testcaseData;
}
public void setTestcaseData(final TestCaseData testcaseData) {
this.testcaseData = testcaseData;
}
}
import org.codehaus.jackson.annotate.JsonProperty;
public class TestCaseData {
private String sequence;
private int testNumber;
private String testCaseFile;
@JsonProperty("-sequence")
public String getSequence() {
return this.sequence;
}
public void setSequence(final String sequence) {
this.sequence = sequence;
}
@JsonProperty("-testNumber")
public int getTestNumber() {
return this.testNumber;
}
public void setTestNumber(final int testNumber) {
this.testNumber = testNumber;
}
@JsonProperty("-testCaseFile")
public String getTestCaseFile() {
return this.testCaseFile;
}
public void setTestCaseFile(final String testCaseFile) {
this.testCaseFile = testCaseFile;
}
}
public static void main(final String[] args) {
final String json = "{\"TestSuite\":{\"TestSuiteInfo\":{\"-description\":\"parse\"},\"TestCase\":[" +
"{\"TestCaseData\":{\"-sequence\":\"sequential\",\"-testNumber\":\"2\",\"-testCaseFile\":\"testcase\\\\Web\\\\Ab.xml\"}}," +
"{\"TestCaseData\":{\"-sequence\":\"sequential\",\"-testNumber\":\"3\",\"-testCaseFile\":\"testcase\\\\Web\\\\BC.xml\"}}" +
"]}}";
final ObjectMapper mapper = new ObjectMapper();
try {
final OverallWrapper readValue = mapper.readValue(json, OverallWrapper.class);
System.out.println(readValue.getTestSuite());
}
catch (final Exception e) {
e.printStackTrace();
}
}
加起来
最终的问题是域无法与 JSON 结合起来。
就我个人而言,我更喜欢更改 JSON 以与域结合,因为域的设计似乎很有意义,并且需要较少的定制和强制。
但是,我确实承认您可能没有这种选择,因此需要重新设计域。