Jackson的使用详解–ObjectMapper

Jackson的使用详解–ObjectMapper

前言

项目中需要用jackson替换fastjson,因为自己对json了解不是很多,所以通过看视频与相关文章写了一个通用的jackson工具类,这篇文章是自己做一个总结

一.什么是序列化,什么是反序列化。

1.序列化

序列化是指将对象转化成字节序列,方便持久化存储到磁盘,避免程序运行结束后对象就从内存里消失,另外变换成字节序列也更便于网络运输和传播

2 反序列化

反序列化就是指将字节序列转化成对象

二.常用的三种json工具:Fastjson,Jackson,Gson

对于Json 框架来说、想要把一个 Java 对象转换成字符串、有两种选择:

  • 基于属性
  • 基于 setter/getter

FastJson 和 Jackson 在把对象序列化成 json 字符串的时候、是通过遍历该类中所有 getter 方法进行的。Gson并不是这么做的,他是通过反射遍历该类中的所有属性,并把其值序列化成json。

三.Java中如何使用Jackson

jackson主要用到的工具类是ObjectMapper,使用ObjectMapper可以基本解决序列化问题

1. ObjectMapper初始化

public class JacksonUtil { 
	private static ObjectMapper objectMapper =new ObjectMapper();
	/** 默认日期时间格式 */
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    /** 默认日期格式 */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    /** 默认时间格式 */
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
    static {//初始化
        //设置date属性
        SimpleDateFormat dateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        objectMapper.setDateFormat(dateFormat);
        objectMapper.setTimeZone(TimeZone.getTimeZone("GTM+8"));
        //当JSON数据的属性多于java对象属性时,会抛异常,这时,需要通过配置Jackson的Feature使能可以让你忽略那些多余的属性
        objectMapper.configure(
                DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //设置LocalDateTime,LocalDate,LocalTime
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new 						LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
        objectMapper.registerModule(javaTimeModule);
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
         //空指针不报错
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
          //未知错误不报错
        objectMapper.disable(SerializationFeature.FAIL_ON_UNWRAPPED_TYPE_IDENTIFIERS);
         //支持null和空串
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        //下边这些配置根据自己项目实际情况加,反正我是都用到了
        //字符串中允许单引号
        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES,true);
        //表示字符串中也可以无引号
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES,true);
        //允许支持JSON数组中“缺失”值,数组中缺失了值表示两个逗号之间,啥都没有,形如这样[value1, , value3]。
        objectMapper.configure(JsonParser.Feature.ALLOW_MISSING_VALUES,true);
        //允许像00001这样的“数字”出现(而不报错)
        objectMapper.configure(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS,true);
        //允许**反斜杠**转义任何字符
        objectMapper.configure(JsonParser.Feature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER,true);
        //允许/* */或者//这种类型的注释出现。
        objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS,true);
        //支持Yaml格式的的注释,也就是#形式的注释语法。形如 {"table#abd":"test"}
        objectMapper.configure(JsonParser.Feature.ALLOW_YAML_COMMENTS,true);
         //支持结尾逗号{"name":"小明","age": "18",}
        objectMapper.configure(JsonParser.Feature.ALLOW_TRAILING_COMMA, true);
    }
}

2. Object 转 JSON

    public static String toJSONString(Object o) {
        String json =null;
        try {
             json =objectMapper.writeValueAsString(o);
        }catch (JsonProcessingException e){
            System.out.println(e.getMessage());
        }
        return json;
    }

3. json格式或者JsonNode,ArrayNode,ObjectNode 转 Object

 public static <T> T parseObject(Object text,Class<T> clazz)   {
        if (text==null){
            return  null;
        }else {
            T json = null;
            try {
                if (text instanceof JsonNode){
                    T pojo =  objectMapper.convertValue(text,clazz);
                    return pojo;
                }
                if (text instanceof ArrayNode){
                    T pojo =  objectMapper.convertValue(text,clazz);
                    return pojo;
                }
                if (text instanceof ObjectNode){
                 T pojo =  objectMapper.convertValue(text,clazz);
                 return pojo;
                }
                if (text instanceof String){
                    String resut =text.toString();
                    json = objectMapper.readValue(resut, clazz);
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
            return json;
        }
    }

4.JSON 转 数组

json转数组 其实跟上边 3的用法差不多,都可以达到同样的效果,但是因为要模仿fastjson的方法,这样改起来会方便一点

    public static <T> List<T> parseArray(String text, Class<T> clazz)  {
        if (text==null){
            return  null;
        }else {
            try {
                return objectMapper.readValue(text, objectMapper.getTypeFactory().constructParametricType(List.class, clazz));
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
            return null;
        }
    }

5.JSON 转 jsonNode

jsonNode 相当于fastjson的JSONObject,不过jsonNode侧重于读取,并不支持写入操作

   public static JsonNode parseObject(String text){
        JsonNode jsonNode = null;
        try {
             jsonNode = objectMapper.readTree(text);
            if (jsonNode.isNull()){
                return null;
            }
        }catch (IOException e){
            System.out.println(e.getMessage());
        }
        return jsonNode;
    }

常用用法

    public static void main(String[] args) {
         Map<String,Object> map1 =new HashMap<>();
        map1.put("小明","男");
        map1.put("test",map);
        String jason =JacksonUtil.toJSONString(map1);
        JsonNode jsonNode =JacksonUtil.parseObject(jason);
        jsonNode.asText();//类似于fastjson中的getString(),一定不要用toString,本身就是字符串了,在toString会""""
        jsonNode.isArray();//判断是否是数组
        jsonNode.get("key");//获取json字符串中的对象属性
        jsonNode.elements();//如果在判断为数组的前提下,可以进行遍历(与ArrayNode.elements()一样)
    }

6.ObjectMapper 创建 ObjectNode

    //objectNode一般用于写操作,可以用于转换成ArrayNode,ArrayNode相当于fastjson的JSONArray
	public static ObjectNode objectNode(){
        ObjectNode jsonNode = null;
        jsonNode = objectMapper.createObjectNode();
        return jsonNode;
    }

常用用法

    public static void main(String[] args) {
        ObjectNode newNode =objectMapper.createObjectNode();
        newNode.put("list", String.valueOf(response));//新增基本数据类型
        newNode.putPOJO("list",response);//新增object
       ArrayNode arrayNode= newNode.putArray("ada");//创建ArrayNode
    }

7.创建ArrayNode

1.通过JsonNodeFactory创建

        ArrayNode arrayNode =JsonNodeFactory.instance.arrayNode();

2.通过ObjectNode创建

	//必须赋予key值	
	ArrayNode arrayNode =objectNode.putArray("key");

3.常用用法

    public static void main(String[] args) {
        ArrayNode arrayNode =JsonNodeFactory.instance.arrayNode();
        arrayNode.addPOJO("dad");//添加Object
        arrayNode.add();//添加基本数据类型
        Iterator<JsonNode> iterator =arrayNode.elements();//迭代器遍历数组
        arrayNode.size();//获取数组长度
    }

ArrayNode,ObjectNode,jsonNode的具体用法就不一一细说了,大家可以在搜其他的文章获取具体用法

Jackson常用注解

1.@JsonProperty,@JsonAlias

两者都是为对象属性定义一个别名,区别在于@JsonAlias是在反序列化时根据别名进行属性映射,而@JsonProperty是序列化和反序列化都会进行映射

@Getter
@Setter
public class User {

	@JsonAlias(value = "nm")
	private String name;
	private Integer age;
}

2.@JacksonInject

通过 @JacksonInject 注解可以在 Jackson 反序列化的时候为空值字段动态赋值,当反序列化的对应属性值不存在时,可通过该注解为其动态设置值。

@Getter
@Setter
public class User {

    @JacksonInject(value = "dynamic")
    private String name;
    private Integer age;

}

3.@JsonIgnore

在序列化、反序列化时会忽略被该注解标记的属性。

@Getter
@Setter
public class User {

    @JsonIgnore
    private String name;
    private String age;
}

注意事项

1.JSONObject的toString并不等同于JsonNode的toString,fastjson的toSting是序列化过的,与toJSONString一样,所以toString就意味着是序列化了,JsonNode只是单纯的变字符串。

你可能感兴趣的:(java,json,前端)