我有一些代码需要一个字节数组。转换为String时,这些字节应该是有效的JSON字符串。如果不是,它将使用“Uknown”作为密钥将String转换为有效的JSON。
除了我发现的一个边缘情况外,它工作正常。如果我传递一个包含多个有效JSON字符串的String,它只解析第一个String并认为它是有效的JSON。我宁愿它评估整个String并确定它是无效的JSON,因为它是2个或更多单独的有效JSON字符串。然后,它将使单独的JSON字符串成为一个有效的JSON字符串,就像它对任何其他无效JSON的字符串一样。
我正在使用Jackson 2.8.1。
下面是一个演示此问题的小应用程序。任何帮助将不胜感激。
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class EnsureValidJSON {
private static ObjectMapper objectMapper = new ObjectMapper();
public static void main(String[] args) {
String input = "{\"Message1\" : \"This is the first message\"}{\"Message2\" : \"This is the second message.\"}";
System.out.println("input: " + input);
byte[] msg = input.getBytes();
try {
msg = ensureMsgIsValidJson(msg);
} catch (IOException e) {
// Default to Unknown:Unknown
msg = "{\"Unknown\" : \"Unknown\"}".getBytes();
}
System.out.println("output: " + new String(msg));
}
private static boolean isJSONValid(byte[] msg) {
boolean isValid = false;
try {
JsonNode jsonNode = objectMapper.readTree(msg);
// Print out the field names and their values to show that it is only parsing the first Json String.
Iterator<String> itr = jsonNode.fieldNames();
while (itr.hasNext()) {
String fieldName = itr.next();
System.out.print(fieldName + ": ");
System.out.println(jsonNode.get(fieldName));
}
isValid = true;
} catch (IOException e) {
String err = String.format("%s is an invalid JSON message. We will attempt to make the message valid JSON. Its key will be 'Unknown'.", new String(msg));
System.out.println(err);
}
return isValid;
}
private static byte[] ensureMsgIsValidJson(byte[] msg) throws IOException {
if (isJSONValid(msg)) {
return msg;
}
return createValidJSON(msg);
}
private static byte[] createValidJSON(byte[] msg) throws IOException {
JsonFactory factory = new JsonFactory();
try (OutputStream out = new ByteArrayOutputStream()) {
JsonGenerator generator = factory.createGenerator(out);
generator.writeBinary(msg);
JsonNodeFactory nodeFactory = new JsonNodeFactory(false);
ObjectNode validated = nodeFactory.objectNode();
objectMapper.writeTree(generator, validated);
validated.put("Unknown", new String(msg));
byte[] validatedBytes = objectMapper.writeValueAsBytes(validated);
String message = String.format("Message(%s) was successfully converted to a valid JSON message: %s", new String(msg), new String(validatedBytes));
System.out.println(message);
return validatedBytes;
}
}
}
答案 0 :(得分:1)
我必须使用jackson JsonParser对象来计算打开和关闭大括号的数量。如果计数为0且String中没有任何内容,则其中只有一个JSON字符串。我还必须添加代码来检查值是否为数值,因为如果值的计算结果为数字,ObjectMapper的readTree方法将不会抛出IOException。
我想要编写更多代码来完成这项工作,但它确实有效:
print 'message', '\r',
print 'this new message now covers the previous'