fasterxml解析json篇
程序员文章站
2022-03-10 12:13:18
...
1
github demo:https://github.com/FasterXML/jackson-databind
2
maven依赖:
<dependency.version.jackson>2.8.8</dependency.version.jackson>
<!-- Jackson依赖库 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${dependency.version.jackson}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${dependency.version.jackson}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${dependency.version.jackson}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${dependency.version.jackson}</version>
</dependency>
<!-- 以下是bean复制工具 -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.7.0</version>
</dependency>
JacksonUtil.java
public class JacksonUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(JacksonUtil.class);
private static final ObjectMapper objectMapper = new ObjectMapper();
static {
/*
* 默认false:不解析含有注释符(即:true时解析含有注释的json字符串)<br>
* 该特性,决定了解析器是否可以解析含有Java/C++注释样式(如:/*或//的注释符)<br>
* 注意:标准的json字符串格式没有含有注释符(非标准),然而则经常使用<br>
*/
objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
/*
* 默认false:不解析含有结束语的字符<br> 该特性,决定了解析器是否可以解析该字符(结束语字段符,一般在js中出现)<br>
* 注意:标准的json字符串格式没有含有注释符(非标准),然而则经常使用<br>
*/
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
/*
* 默认false:不解析含有单引号的字符串或字符<br>
* 该特性,决定了解析器是否可以解析单引号的字符串或字符(如:单引号的字符串,单引号'\'')<br>
* 注意:可作为其他可接受的标记,但不是JSON的规范<br>
*/
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
/*
* 允许:默认false_不解析含有结束语控制字符<br>
* 该特性,决定了解析器是否可以解析结束语控制字符(如:ASCII<32,如包含tab或换行符)<br>
* 注意:设置false(默认)时,若解析则抛出异常;若true时,则用引号即可转义<br>
*/
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
/*
* 可解析反斜杠引用的所有字符,默认:false,不可解析
*/
objectMapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER, true);
/**
* 按字母顺序排序
*/
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
/**
* 忽略null
*/
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.setLocale(Locale.CHINA);
objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
// 将locadatetime 按照yyyy-MM-dd HH:mm:ss打印
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class,
new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
objectMapper.registerModule(javaTimeModule);
}
/**
* 对象转JSON
*
* @param object
* 对象
* @return String
*/
public static String toJSONString(Object object) {
String json = "";
if (null == object) {
return json;
}
try {
json = objectMapper.writeValueAsString(object);
} catch (IOException e) {
LOGGER.error("Java 转 JSON 出错!", e);
e.printStackTrace();
}
return json;
}
/**
* 对象转JSON
*
* @param object
* 对象
* @param pattern
* 字符串时间格式规则, 如 "yyyy-MM-dd HH:mm:ss"
* @return String
*/
public static String toJSONString(Object object, String pattern) {
String json = "";
if (null == object) {
return json;
}
ObjectMapper mapper = objectMapper;
try {
DateFormat dateFormat = new SimpleDateFormat(pattern);
mapper = mapper.setDateFormat(dateFormat);
json = mapper.writeValueAsString(object);
} catch (IOException e) {
LOGGER.error("Java 转 JSON 出错!", e);
e.printStackTrace();
}
return json;
}
/**
* 将json字符串转换为java对象
*
* @param json
* json字符串
* @param typeReference
* 复杂的java对象类型
* @param <T>
* @return
*/
public static <T> T jsonToBean(String json, TypeReference typeReference) {
try {
return objectMapper.readValue(json, typeReference);
} catch (Exception e) {
LOGGER.error("jsonToBeanByTypeReference", e);
e.printStackTrace();
}
return null;
}
/**
* map 转JavaBean
*/
public static <T> T map2bean(Map map, Class<T> clazz) {
return objectMapper.convertValue(map, clazz);
}
}
3 使用
1 映射entity
jsonToBean:
List<JsonEntity> jsonEntityList = JacksonUtil.jsonToBean(message, new TypeReference<List<JsonEntity>>(){});
注意:entity不要定义成List。
2 直接读取
示例:
public List<UserEventEntity> parse(String message) throws IOException{
List<UserEventEntity> list = new ArrayList<>();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(message);
boolean active = jsonNode.get("Hadoop:service=NameNode,name=FSNamesystem").get("tag.HAState").textValue().equals("active");
if(active){
JsonNode innerNode = objectMapper.readTree(jsonNode.get("Hadoop:service=NameNode,name=FSNamesystemState").get("TopUserOpCounts").textValue());
/**
* topUserOpCounts 结构:
* topUserOpCounts (string) : v (string) 其中String类型的v如下: (即innerNode)
*
* {
* "timestamp": "2019-06-25T16:57:11+0800",
* "windows": [{
* "windowLenMs": 60000,
* "ops": [{
* "opType": "listStatus",
* "topUsers": [{
* "user": "voyager",
* "count": 82
* },
* {
* "user": "wave_bi",
* "count": 1
* }
* ],
* "totalCount": 83
* }]
* }]
* }
*
* 其中,需要set给entity的字段如下:
* timestamp : 上述的timestamp字段如xxx
* opType : 上述的opType
* opTotalSum: 将totalCount放在每个topUsers中的值,每个user都含有一样的总值
* userName : 上述user
* opSum : 上述count
* windowLenMs:放到每个user中
*
* 另外,额外设置一个entity,其 user = all ,并设置其 opTotalSum
*/
String timestamp = innerNode.get("timestamp").textValue();
innerNode.get("windows").forEach(e-> {
long windowLenMs = e.get("windowLenMs").longValue();
e.get("ops").forEach(f->{
String opType = f.get("opType").textValue();
long totalCount = f.get("totalCount").longValue();
UserEventEntity a = new UserEventEntity();
a.setUserName("all"); //这是一个统计用户
a.setOpTotalSum(totalCount);
a.setOpSum(totalCount);
a.setOpType(opType);
a.setWindowLenMs(windowLenMs);
a.setTimestamp(timestamp);
list.add(a);
f.get("topUsers").forEach(g->{
String user = g.get("user").textValue();
long count = g.get("count").longValue();
UserEventEntity u = new UserEventEntity();
u.setTimestamp(timestamp);
u.setWindowLenMs(windowLenMs);
u.setOpType(opType);
u.setUserName(user);
u.setOpSum(count);
u.setOpTotalSum(totalCount);
list.add(u);
});
});
});
}
return list;
}
上一篇: 疯狂XML学习笔记(2)-------------格式要求
下一篇: Redis 发布订阅