作为json序列化框架的潮流 jackson有其独到的优势,至少在生产环境上是安全可靠的(diss某巴的json,报个bug全公司跟着升级), 当然也有老大为了统一使用原因啦,话不多说,看看使用
任何新框架使用时离不开三步走
1.加依赖
2.写代码【要么加启动注解,要么就是加初始化配置】
3. 用
值得庆幸的是: SpringBoot的默认就带Jackson依赖 具体体现在web场景的那个jar
spring-boot-starter-web.jar
如果还是Spring项目,需要引入三个jar。版本选择2.7.9 【使用最多】(用得少的先让他们踩坑去)
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>${jackson-version-core}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>${jackson-annotations-version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>${jackson-databind-core}version>
dependency>
现在进行第二步: 初始化配置, jackson在使用时 是需要一定配置的 如下代码来自我司业务使用的工具类
public class JsonUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(JsonUtil.class);
private static ObjectMapper mapper = new ObjectMapper();
static {
// 序列化:驼峰转下划线且小写 反序列化: 自动还原
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, Boolean.FALSE);
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, Boolean.TRUE);
}
public static ObjectMapper getMapper() {
return mapper;
}
public static String objectToJSON(Object any) {
try {
return mapper.writeValueAsString(any);
} catch (JsonProcessingException e) {
LOGGER.error("convert object to json exception, {}", e.getMessage());
e.printStackTrace();
}
return null;
}
public static <T> T jsonToObject(String json, Class<T> T) {
try {
return mapper.readValue(json, T);
} catch (IOException e) {
LOGGER.error("convert json to object exception, {}", e.getMessage());
e.printStackTrace();
}
return null;
}
public static <T> List<T> jsonToListObject(String json, Class<T> T) {
try {
return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, T));
} catch (IOException e) {
LOGGER.error("convert json to object list exception, {}", e.getMessage());
e.printStackTrace();
}
return null;
}
public static boolean isJson(String json) {
try {
JSONObject.parseObject(json);
return true;
} catch (Exception ex) {
return false;
}
}
}
注: 部分coding来自笔者哦
普通用法
public static void main(String[] args) {
User user = new User();
user.setUserId(11L);
user.setUserName("aa");
String s = objectToJSON(user);
// {"user_id":11,"user_name":"aa","email":null}
// User(userId=11, userName=aa, email=null)
System.out.println(s);
System.out.println(jsonToObject(s, User.class));
}
复杂用法
// 将嵌套的json串 解析成树形结构
JsonNode jsonNode = mapper.readTree(str);
// 获取目标key的json串
JsonNode result = jsonNode.get("result");
// 将所有key 为id对应的value值 都查出来 不一定只有同级!
List<JsonNode> result1 = jsonNode.findValues("id");
// 扩展:
List<Long> collect = result1.stream().map(r -> Long.valueOf(r.toString())).collect(Collectors.toList());
// 只查询第一个匹配到的记录
JsonNode id = jsonNode.findValue("id");
// 查询json串中是否有key为result的串 可以做判断空处理
boolean exist = jsonNode.has("result")
// 查询将查询到json value 解析成目标类型 如果解析不成功可以指定默认value 适用于解析容错的场景
JsonNode id = jsonNode.findValue("real_name");
long l = id.asLong(22L);
// 预判节点类型 isXX
// 是否包含子节点 isContainerNode
// 基于url方式查找所有key为id 所有value 注意:改方式不能直接转成list
JsonNode path = jsonNode.findPath("list/id");
注意: 获取无论哪种方式获取JsonNode 请一定要判断空!
@JsonProperty("userName") 作用属性上 为属性起别名
@JsonTypeName(value = "user") 和@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT) 作用在类上,序列化的时候在包裹一层: key是user
@JsonTypeName(value = "root")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT)
// {"user":{"user_id":11,"user_name":"aa"}}
@JsonRootName(value="user") 和 mapper.enable(SerializationFeature.WRAP_ROOT_VALUE); 效果和上面类似,只不过是全局配置方式
@JsonIgnoreProperties() 作用在类上,序列化的忽略的属性