- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一些代码需要一个字节数组。这些字节在转换为字符串时应该是有效的 JSON 字符串。如果不是,它将使用“Uknown”作为其键将字符串转换为有效的 JSON。
除了我发现的一种极端情况外,它工作正常。如果我向它传递一个包含多个有效 JSON 字符串的字符串,它只会解析第一个字符串并认为它是有效的 JSON。我宁愿它评估整个字符串并确定它不是有效的 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;
}
}
}
最佳答案
我必须使用 jackson JsonParser 对象来计算左大括号和右大括号的数量。如果计数为 0 并且 String 中没有任何内容,则它只包含一个 JSON String。我还必须添加代码来检查该值是否为数字,因为如果该值的计算结果为数字,ObjectMapper 的 readTree 方法将不会抛出 IOException。
这是我想要编写的更多代码来完成它,但它有效:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Scanner;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
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) {
if (args.length == 0) {
System.err.println("You must pass at least one String to be validated.");
} else {
for (String arg : args) {
System.out.println("input: " + arg);
byte[] msg = arg.getBytes();
try {
msg = ensureMsgIsValidJson(msg);
} catch (IOException e) {
msg = "{\"Unknown\" : \"Unknown\"}".getBytes();
}
System.out.println("output: " + new String(msg));
}
}
}
private static boolean isJSONValid(byte[] msg) {
return isJSONFormat(msg) && isJSONOneMessage(msg);
}
private static boolean isJSONFormat(byte[] msg) {
boolean isValid = false;
String rawString = new String(msg).trim();
try (Scanner sc = new Scanner(rawString)) {
objectMapper.readTree(msg);
// If the value evaluates to a number, objectMapper.readTree will not throw an Exception, so check that here.
if (sc.hasNextLong() || sc.hasNextDouble()) {
String err = String.format("%s is an invalid JSON message because it is numeric.", rawString);
System.out.println(err);
} else {
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'.", rawString);
System.out.println(err);
}
return isValid;
}
private static boolean isJSONOneMessage(byte[] msg) {
boolean isValid = false;
try {
JsonParser parser = objectMapper.getFactory().createParser(msg);
JsonToken token;
// balance will increment with each opening curly bracket and decrement with each closing curly bracket. We'll use this to ensure that this is only one JSON message.
int balance = 0;
while ((token = parser.nextToken()) != null) {
if (token.isStructStart()) {
balance++;
} else if (token.isStructEnd()) {
balance--;
}
if (balance == 0) {
break;
}
}
isValid = parser.nextToken() == null;
} catch (IOException e) {
String err = String.format("'%s' is an invalid JSON message due to the following error: '%s'. We will attempt to make the message valid JSON. Its key will be 'Unknown'.", new String(msg),
e.getMessage());
System.out.println(err);
}
return isValid;
}
private static byte[] ensureMsgIsValidJson(byte[] msg) throws IOException {
return isJSONValid(msg) ? msg : 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;
}
}
}
关于java - jackson 在第一次关闭大括号后停止读取输入字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40142678/
我找不到关于 jackson 的ObjectMapper与其他映射器(例如dozer/mapStruct/modelMapping/etc)之间的区别的任何解释。所有文章都比较了dozer/mapSt
我正在使用Jackson来反序列化Kotlin数据类。我正在使用jackson-kotlin-module,但 jackson 却给我以下错误: Can not construct instance
我正在尝试将包从“com.fasterxml.jackson”重新定位到我自己的包(即“mypackage.com.fasterxml.jackson”),然后在我拥有的另一个 JAR 中使用它。 我
对于JSON对象,Subject: { "permissions":["foo", "bar"], ... } ...我想反序列化为: class Subject { priv
我正在使用 @JsonTypeInfo 和 @JsonSubTypes 来映射基于给定属性的解析子类。这是我想要解析的示例 JSON 的一个人为示例。 { "animals": [ { "
我们正在使用 dropwizard 版本 0.6.3。当我们尝试升级 0.7.0 版本时,我们在服务启动时收到此错误。 线程“main”中的异常 java.lang.VerifyError: clas
我正在尝试实现自定义解串器。因为我只想向默认反序列化器添加功能,所以我尝试在我的自定义反序列化器中存储默认反序列化器:我想使用默认反序列化 json,然后添加其他信息。 我正在尝试使用 BeanDes
我有一个这样的类(class): public class Person { private String name; public String getName(){ return
我有以下 Kotlin 数据类: data class TestObject( val boolField: Boolean, val stringField: Str
使用 Jackson 库,在 Eclipse 4.9.0 版本中出现以下错误 缺少工件 com.fasterxml.jackson.core:jackson-databind:bundle:2.9.6
我试图在我的应用程序中从azure实现keyvault,在为DefaultAzureCredentialBuilder()实现azure-identity:1.5.4 lib后,它会抛出链接错误,如下
我试图在我的应用程序中从azure实现keyvault,在为DefaultAzureCredentialBuilder()实现azure-identity:1.5.4 lib后,它会抛出链接错误,如下
我知道我们可以使用 Jackson MixIn 来重命名属性或忽略属性(参见示例 here )。但是可以添加属性吗? 添加的属性可以是: 一个常数(如版本号) 计算值(例如,如果源类具有 getWid
我有一个在 Wildfly 10 上运行的应用程序,它需要更新版本的 jackson。简单地更新 maven 依赖是行不通的。 Wildflys 自己的版本似乎干扰了... 有人有提示吗? 最佳答案
我在 Tomcat 休息应用程序中运行 Jersey 2.5.1 & Jackson。对于我最初将 POJO 简单地转换为 JSON 的用例,基本设置效果很好。集合很好地转换为 json 数组,如下所
有没有办法告诉 jackson 在序列化过程中忽略那些用非 jackson 注释注释的字段? 例如: @SomeAnnotation private String foo; 我知道有 jackson
我遇到了 jackson 序列化问题, map 中存在空值。显然,这是 Wildfly 9 使用的 Jackson 版本中的一个已知错误 ( https://issues.jboss.org/brow
给定一个像这样的 JSON 映射类: public class Person { @JsonProperty String getName() { ... } @JsonPro
如何让 Jackson 的 XMLMapper 在反序列化时读取根 xml 元素的名称? 我正在将输入 XML 反序列化为通用 Java 类、LinkedHashMap,然后反序列化为 JSON。我想
我对抽象类和 JSON 序列化和反序列化的对象引用有问题。抽象的问题如下所示: 我有一个由节点和边组成的图。每条边连接两个节点。节点可以是红色和绿色的。因此,有一个抽象类Node和两个派生类 RedN
我是一名优秀的程序员,十分优秀!