我正在为Vert.x实现编写框架级别的代码,该代码在所有api调用到达其相应的处理程序之前都像“拦截器”一样运行。
此“拦截器”针对每个API调用运行时,它需要处理各种Json请求:
{
"fname":"John",
"lname":"Cena"
}
[
{
"fname":"John",
"lname":"Cena"
},
{
"fname":"Shawn",
"lname":"Michaels"
}
]
根据输入,我想确定,我应该将requestBody解析为JsonObject还是JsonArray 。有关请求解析的所有内容(如标头,查询参数,路径参数)均保持不变。 我知道我可以做类似的事情:
public static int decideObjectOrArray(String requestBody) {
Object json = new JSONTokener(requestBody).nextValue();
if(json instanceof JSONObject) {
return 1;
}
//you have an object
else if(json instanceof JSONArray) {
return 2;
}
//you have an array
return 0;
}
但这需要在pom中添加以下新依赖项:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
使用本机vertx json包是否可以实现相同的行为?
答案 0 :(得分:1)
您可以使用Vert.x JsonParser
确定内容的类型:
private Object parse(Buffer buffer) {
JsonParser parser = JsonParser.newParser();
AtomicReference<Object> result = new AtomicReference<>();
parser.handler(event -> {
switch (event.type()) {
case VALUE:
Object res = result.get();
if (res == null) {
result.set(event.value());
} else if (res instanceof List) {
List list = (List) res;
list.add(event.value());
} else if (res instanceof Map) {
Map map = (Map) res;
map.put(event.fieldName(), event.value());
}
break;
case START_ARRAY:
result.set(new ArrayList());
parser.objectValueMode();
break;
case START_OBJECT:
result.set(new HashMap());
parser.objectValueMode();
break;
}
});
parser.handle(buffer);
parser.end();
Object res = result.get();
if (res instanceof List) {
return new JsonArray((List) res);
}
if (res instanceof Map) {
return new JsonObject((Map<String, Object>) res);
}
return res;
}
然后,如果您使用不同类型的内容调用此方法:
parsed = jsonTest.parse(Buffer.buffer("[1,2,3]"));
System.out.println(parsed.getClass().getName() + " : " + parsed);
System.out.println();
parsed = jsonTest.parse(Buffer.buffer("{\"hello\": \"world\"}"));
System.out.println(parsed.getClass().getName() + " : " + parsed);
System.out.println();
parsed = jsonTest.parse(Buffer.buffer("\"text\""));
System.out.println(parsed.getClass().getName() + " : " + parsed);
您将通过相应的类获得结果:
io.vertx.core.json.JsonArray : [1,2,3]
io.vertx.core.json.JsonObject : {"hello":"world"}
java.lang.String : text
这仅是示例,您需要使用instanceof
测试结果对象。
编辑:如果您想避免流解析器(可能会更慢),则可以直接使用Jackson API:
private Object parse(Buffer buffer) {
Object value;
try {
value = Json.mapper.readValue(buffer.getBytes(), Object.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
if (value instanceof List) {
List list = (List) value;
return new JsonArray(list);
} else if (value instanceof Map) {
Map map = (Map) value;
return new JsonObject(map);
}
return value;
}
您将得到相同的结果。
编辑2 :从method has been added到Buffer
,将内容解析为JSON。它将在下一个Vert.x版本(3.7)中发布。
答案 1 :(得分:0)
首先,在处理正文时,您应该在Buffer
上进行操作,而不要在String
上进行操作。
使用Buffer
时,您可以使用toJsonArray()
和toJsonObject()
。
尽管跳过缓冲区搜索第一个[
或{
也是有效的选择。