Jackson最常用配置与注解

不打扰是莪最后的温柔 提交于 2020-11-04 09:37:16

一、bean

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

public class Result<T> {

    private Integer code;
    private String message;
    private Date time;
    private T data;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Date getTime() {
        return time;
    }

    public void setTime(Date time) {
        this.time = time;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", time=" + time +
                ", data=" + data +
                '}';
    }

    static Result getResult(){
        Result<List<String>> result = new Result<>();
        result.setCode(200);
        result.setTime(new Date());
        result.setMessage("Hello Jackson!");
        LinkedList<String> strings = new LinkedList<>();
        strings.add("aa");
        strings.add("bb");
        strings.add("cc");
        result.setData(strings);
        return result;
    }
}

二、系列化

import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.junit.Test;

import java.io.IOException;
import java.io.StringWriter;

public class JacksonSerTest {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Test
    public void writeValueAsString() throws JsonProcessingException {
        //1.8新添加的时间相关类适配
        objectMapper.registerModule(new JavaTimeModule());
        String value = objectMapper.writeValueAsString(Result.getResult());
        System.out.println(value);
    }

    @Test
    public void writeValue() throws IOException {
        //直接写OutputStream
        objectMapper.writeValue(System.out,Result.getResult());
    }

    @Test
    public void toWriter() throws IOException {
        StringWriter stringWriter = new StringWriter();
        //写Writer
        objectMapper.writeValue(stringWriter,Result.getResult());
        System.out.println(stringWriter.toString());
    }

    @Test
    public void jsonGenerator() throws IOException {
        JsonGenerator jsonGenerator = objectMapper.getFactory().createGenerator(System.out, JsonEncoding.UTF8);
        objectMapper.writeValue(jsonGenerator,Result.getResult());
    }

    @Test
    public void writeObject() throws IOException {
        JsonGenerator jsonGenerator = objectMapper.getFactory().createGenerator(System.out, JsonEncoding.UTF8);
        jsonGenerator.writeObject(Result.getResult());
    }

}

三、反系列化

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

import java.util.Iterator;
import java.util.Map;

public class JacksonDesTest {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    public static final String content = "{\"code\":200,\"message\":\"Hello Jackson!\",\"time\":1572948614250,\"data\":[\"aa\",\"bb\",\"cc\"]}";

    @Test
    public void readValue() throws JsonProcessingException {
        Result result = objectMapper.readValue(content, Result.class);
        System.out.println(result);
    }

    @Test
    public void readMap() throws JsonProcessingException {
        Map map = objectMapper.readValue(content, Map.class);
        System.out.println(map.get("code"));
        System.out.println(map.get("data"));
    }

    @Test
    public void readTree() throws JsonProcessingException {
        JsonNode jsonNode = objectMapper.readTree(content);
        JsonNode code = jsonNode.get("code");
        System.out.println(code.asInt());
        JsonNode data = jsonNode.get("data");
        Iterator<JsonNode> elements = data.elements();
        while (elements.hasNext()){
            JsonNode next = elements.next();
            System.out.println(next.asText());
        }
    }
}

四、配置

参数 说明 默认值
INDENT_OUTPUT 格式化输出 false
WRITE_DATES_AS_TIMESTAMPS date是否系列化为时间戳 true
WRITE_DATE_KEYS_AS_TIMESTAMPS date作为map的key是否系列化为时间戳 true
WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS char[]是否转为字符串 false
WRITE_ENUMS_USING_TO_STRING 枚举是否使用Enum.toString(),否则Enum.name() false
WRITE_ENUMS_USING_INDEX 枚举值是否序列化为数字 false
WRITE_ENUM_KEYS_USING_INDEX Map的key是枚举的时候使用数字 false

jackson最常用配置

2中配置方式

ObjectMapper mapper = new ObjectMapper();
// 下面2中方式等价
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,true);
objectMapper.enable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// 下面2中方式等价
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.junit.Test;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JacksonConfigTest {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Test
    public void config() throws JsonProcessingException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        objectMapper.setDateFormat(sdf);
        // 格式化输出
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);
        // Date不要转为时间戳
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        //Map的key为Date的时候转为时间戳
        objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS,true);
        //char[]数组转为字符串
        objectMapper.configure(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS,false);
        //枚举值使用ordinal(数字),默认使用的是Enum.name
        objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX,true);
        //使用Enum.toString,需要自定义枚举输出的时候使用
        objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING,true);
        // Map的key是枚举的时候使用数字
        objectMapper.configure(SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX,true);
        String result = objectMapper.writeValueAsString(getConfigBean());
        System.out.println(result);
    }

    @Test
    public void include() throws JsonProcessingException {
        // 属性为Null不系列化
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 属性为默认值不序列化
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
        // 属性为""或者为NULL都不序列化
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        String result = objectMapper.writeValueAsString(getConfigBean());
        System.out.println(result);
    }

    private static ConfigBean getConfigBean(){
        ConfigBean configBean = new ConfigBean();
        configBean.setChars("Jackson".toCharArray());
        Date date = new Date();
        configBean.setDate(date);
//        configBean.setNoGetter("noSetter");
        HashMap<Status, Integer> statusMap = new HashMap<>();
        statusMap.put(Status.SUCCESS,1);
        statusMap.put(Status.FAIL,2);
        configBean.setEnumMap(statusMap);
        HashMap<Date, Integer> dateMap = new HashMap<>();
        dateMap.put(date,1);
        dateMap.put(new Date(),null);
        configBean.setDateMap(dateMap);
        configBean.setStatus(Status.SUCCESS);
        return configBean;
    }

    static class ConfigBean{
        private Date date;
        private char[] chars;
        private Map<Status,Integer> enumMap;
        private Map<Date,Integer> dateMap;
        private String noGetter;
        private Status status;

        public Status getStatus() {
            return status;
        }

        public void setStatus(Status status) {
            this.status = status;
        }

        public Date getDate() {
            return date;
        }

        public void setDate(Date date) {
            this.date = date;
        }

        public char[] getChars() {
            return chars;
        }

        public void setChars(char[] chars) {
            this.chars = chars;
        }

        public Map<Status, Integer> getEnumMap() {
            return enumMap;
        }

        public void setEnumMap(Map<Status, Integer> enumMap) {
            this.enumMap = enumMap;
        }

        public Map<Date, Integer> getDateMap() {
            return dateMap;
        }

        public void setDateMap(Map<Date, Integer> dateMap) {
            this.dateMap = dateMap;
        }
    }

    enum Status{
        SUCCESS(200,"success"),
        FAIL(500,"fail");

        private Integer code;

        private String msg;

        Status(int code, String msg) {
            this.code = code;
            this.msg = msg;
        }

        public Integer getCode() {
            return code;
        }

        public String getMsg() {
            return msg;
        }
    }
}

最常用

INDENT_OUTPUT:格式化,调试的时候检查避免使用其他格式化工具

WRITE_DATES_AS_TIMESTAMPS:客户端有时候需要时间戳,有时候需要格式化字符串

WRITE_ENUMS_USING_INDEX:客户端很多时候对枚举名称没有兴趣

WRITE_ENUMS_USING_TO_STRING:自定义枚举输出的时候需要用到,重写枚举的toString就可以实现,优先级比WRITE_ENUMS_USING_INDEX低

JsonInclude.Include.NON_NULL:不输出空值,非常常用

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX,true);
objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING,true);

五、注解

@JsonProperty:可设置名称和位置

@JsonIgnore:排除属性

@JsonPropertyOrder:属性序列化位置

@JsonFormat:设置格式化

@JsonInclude:满足条件才包含

@JsonRootName:类注解,指定JSON根属性名称

@JsonIgnoreProperties:类注解,序列化忽略属性。反序列化可以配置@JsonIgnoreProperties(ignoreUnknown=true)忽略未知属性

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.junit.Test;

import java.util.Date;

public class JacksonAnnotationTest {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Test
    public void config() throws JsonProcessingException {
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);
        objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE,true);
        String result = objectMapper.writeValueAsString(getConfigBean());
        System.out.println(result);
    }

    private static AnnotationBean getConfigBean(){
        AnnotationBean annotationBean = new AnnotationBean();
        annotationBean.setStatus(true);
        annotationBean.setCode(200);
        annotationBean.setDate(new Date());
        annotationBean.setIgnoreA("ignoreA");
        annotationBean.setIgnoreB("ignoreB");
        annotationBean.setMessage("message");
        annotationBean.setIgnore("ignore");
        return annotationBean;
    }

    @JsonRootName("root")
    @JsonIgnoreProperties({"ignoreA","ignoreB"})
//    @JsonPropertyOrder(alphabetic=true)
    @JsonPropertyOrder({ "code", "message" })
    static class AnnotationBean<T>{
        @JsonFormat(pattern = "yyyy-MM-dd")
        private Date date;

        private Integer code;

        @JsonProperty("msg")
        private String message;

        private boolean status;
        @JsonIgnore
        private String ignore;

        private String ignoreA;

        private String ignoreB;

        @JsonInclude(JsonInclude.Include.NON_NULL)
        private T data;

        public Date getDate() {
            return date;
        }

        public void setDate(Date date) {
            this.date = date;
        }

        public Integer getCode() {
            return code;
        }

        public void setCode(Integer code) {
            this.code = code;
        }

        public String getMessage() {
            return message;
        }

        public void setMessage(String message) {
            this.message = message;
        }

        public boolean isStatus() {
            return status;
        }

        public void setStatus(boolean status) {
            this.status = status;
        }

        public String getIgnoreA() {
            return ignoreA;
        }

        public void setIgnoreA(String ignoreA) {
            this.ignoreA = ignoreA;
        }

        public String getIgnoreB() {
            return ignoreB;
        }

        public void setIgnoreB(String ignoreB) {
            this.ignoreB = ignoreB;
        }

        public T getData() {
            return data;
        }

        public void setData(T data) {
            this.data = data;
        }

        public String getIgnore() {
            return ignore;
        }

        public void setIgnore(String ignore) {
            this.ignore = ignore;
        }
    }
}

@JsonRootName注解要生效SerializationFeature.WRAP_ROOT_VALUE必须设置为true

@JsonPropertyOrder(alphabetic=true):按字母序排序

@JsonPropertyOrder({ "code", "message" }):code,message这2个属性在其他属性前面

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!