天天看點

springboot(三十九)springboot中jackson特殊使用

作者:聰明的晚風zqw

1、全局時間配置

在application.yml中配置

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss           

或在application.properties中配置

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss           

實體中包含時間類型:

/**
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:06
 * @since jdk1.8
 */
@Data
@Builder
public class Model {
    private Integer id;
    private int age;
    private String name;
    private Date createTime;
}           

測試controller:

/**
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:08
 * @since jdk1.8
 */
@RestController
@RequestMapping("/jackson/type1")
public class JacksonType1Controller {
    @GetMapping("/res")
    public Model res() {
        return Model.builder()
                .id(1)
                .age(12)
                .name("xiaoxiao")
                .createTime(new Date()).build();
    }
}           

測試結果:

springboot(三十九)springboot中jackson特殊使用

2、使用@JsonFormat為某個屬性設定序列化方式

實體:

/**
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:06
 * @since jdk1.8
 */
@Data
@Builder
public class Model {
    private Integer id;
    private int age;
    private String name;
    @JsonFormat(pattern = "yyyy/MM/dd HH:mm:ss")
    private Date createTime;
}           

測試controller:

/**
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:08
 * @since jdk1.8
 */
@RestController
@RequestMapping("/jackson/type2")
public class JacksonType2Controller {
    @GetMapping("/res")
    public Model res() {
        return Model.builder()
                .id(1)
                .age(12)
                .name("xiaoxiao")
                .createTime(new Date()).build();
    }
}           
springboot(三十九)springboot中jackson特殊使用

3、使用@JsonPropertyOrder調整屬性的序列化順序

實體:

/**
 *
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:06
 * @since jdk1.8
 */
@Data
@Builder
@JsonPropertyOrder(value={"name", "age"})
public class Model {
    private Integer id;
    private int age;
    private String name;
    private Date createTime;
}           

controller:

/**
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:08
 * @since jdk1.8
 */
@RestController
@RequestMapping("/jackson/type3")
public class JacksonType3Controller {
    @GetMapping("/res")
    public Model res() {
        return Model.builder()
                .id(1)
                .age(12)
                .name("xiaoxiao")
                .createTime(new Date()).build();
    }
}           
springboot(三十九)springboot中jackson特殊使用

4、使用@JsonProperty修改屬性名稱

實體:

/**
 *
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:06
 * @since jdk1.8
 */
@Data
@Builder
public class Model {
    private Integer id;
    private int age;
    //調整序列化的名稱
    @JsonProperty("myName")
    private String name;
    private Date createTime;
}           

controller:

/**
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:08
 * @since jdk1.8
 */
@RestController
@RequestMapping("/jackson/type4")
public class JacksonType4Controller {
    @GetMapping("/res")
    public Model res() {
        return Model.builder()
                .id(1)
                .age(12)
                .name("xiaoxiao")
                .createTime(new Date()).build();
    }
}           
springboot(三十九)springboot中jackson特殊使用

5、使用@JsonInclude使屬性值為null不參與序列化

實體:

/**
 *
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:06
 * @since jdk1.8
 */
@Data
@Builder
public class Model {
    @JsonInclude(value= JsonInclude.Include.NON_NULL)
    private Integer id;
    private int age;
    private String name;
    private Date createTime;
}           

controller:

/**
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:08
 * @since jdk1.8
 */
@RestController
@RequestMapping("/jackson/type5")
public class JacksonType5Controller {
    @GetMapping("/res")
    public Model res() {
        return Model.builder()
                .age(12)
                .name("xiaoxiao")
                .createTime(new Date()).build();
    }
}           

測試結果:

springboot(三十九)springboot中jackson特殊使用

6、使用@JsonIgnore使某個屬性不參與序列化

實體:

/**
 *
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:06
 * @since jdk1.8
 */
@Data
@Builder
public class Model {
    @JsonIgnore
    private Integer id;
    private int age;
    private String name;
    private Date createTime;
}           

controller:

/**
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/6/14 14:08
 * @since jdk1.8
 */
@RestController
@RequestMapping("/jackson/type6")
public class JacksonType6Controller {
    @GetMapping("/res")
    public Model res() {
        return Model.builder()
                .id(1)
                .age(12)
                .name("xiaoxiao")
                .createTime(new Date()).build();
    }
}           
springboot(三十九)springboot中jackson特殊使用

7、自定義注解實作序列化和反序列化

将字元串轉為數組的序列化處理

package com.iscas.base.biz.test.service;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.iscas.common.web.tools.json.JsonUtils;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

/**
 * @author zhuquanwen
 * @version 1.0
 * @date 2022/6/6 14:04
 * @since jdk11
 */
public class CustomSerialize extends JsonSerializer<String> implements ContextualSerializer {
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value == null) {
            gen.writeNull();
        } else {
            TypeReference<List<String>> typeReference = new TypeReference<>() {};
            gen.writeObject(JsonUtils.fromJson(value, typeReference));
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        //判斷beanProperty是不是空
        if (property == null){
            return prov.findNullValueSerializer(property);
        }
        //判斷類型是否是String
        if (Objects.equals(property.getType().getRawClass(),String.class)){
            CustomStrFormatter annotation = property.getAnnotation(CustomStrFormatter.class);
            if (annotation != null){
                // 這裡可以擷取注解中的一些參數
                String pattern = annotation.pattern();
                return this;
            }
        }
        return prov.findValueSerializer (property.getType (), property);
    }
}           

将數組反序列化為JSON字元串的處理

package com.iscas.base.biz.test.service;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.iscas.common.web.tools.json.JsonUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author zhuquanwen
 * @version 1.0
 * @date 2022/6/6 14:04
 * @since jdk11
 */
public class CustomDeserialize extends JsonDeserializer<String> implements ContextualDeserializer {


    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) {
        try {
            if (p != null && StringUtils.isNotEmpty(p.getText())) {
                List<String> strs = new ArrayList<>();
                JsonToken jsonToken;
                while (!p.isClosed() && (jsonToken = p.nextToken()) != null && !JsonToken.FIELD_NAME.equals(jsonToken) &&
                        !JsonToken.END_ARRAY.equals(jsonToken)) {
                    strs.add(p.getValueAsString());
                }
                return JsonUtils.toJson(strs);
            } else {
                return null;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
        //判斷beanProperty是不是空
        if (property == null) {
            return ctxt.findNonContextualValueDeserializer(property.getType());
        }
        //判斷類型是否是String
        if (Objects.equals(property.getType().getRawClass(), String.class)) {
            CustomStrFormatter annotation = property.getAnnotation(CustomStrFormatter.class);
            if (annotation != null) {
                // 這裡可以擷取注解中的一些參數
                String pattern = annotation.pattern();
                return this;
            }
        }
        return ctxt.findContextualValueDeserializer(property.getType(), property);
    }
}           

自定義注解

package com.iscas.base.biz.test.service;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * @author zhuquanwen
 * @version 1.0
 * @date 2022/6/6 14:02
 * @since jdk11
 */
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = CustomSerialize.class)
@JsonDeserialize(using = CustomDeserialize.class)
public @interface CustomStrFormatter {
    // todo 可以定義格式化方式
    String pattern() default "";
}           

實體中使用自定義注解

@Data
    @Accessors(chain = true)
    public static class TestModel {
        private String id;

        private List<String> strs1;

        @CustomStrFormatter
        private String strs2;
    }           

測試:

@RequestMapping("/test/serial")
@RestController
@Slf4j
public class TestJsonFormatterController {

    /**
     * 測試序列化
     * */
    @GetMapping
    public TestModel test1() {
        TestModel testModel = new TestModel();
        testModel.setId("1").setStrs1(List.of("1", "2", "3"))
                .setStrs2("[\"3\", \"4\"]");
        return testModel;
    }

    @PostMapping
    public String test2(@RequestBody TestModel testModel) {
        log.info("接收到的testModel:{}", testModel.toString());
        return "success";
    }
}           

繼續閱讀