SpringBoot使用Json序列化(jackson-fastjson-gson等)

Springboot+json序列化

  • jackson方案
  • fastjson方案
  • gson方案

一、Jackson方案

  • 注意:Springboot默认的json持久化是jackson
1、添加依赖
  • 注意:除了jackson-core 其他都是选填
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.9</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.9.3</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.9</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.9.9</version>
</dependency>
2、配置
2。1、配置项
#时间戳统一转换 
spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
2.1 配置类
@Configuration
public class JacksonConfig {

    @Value("${spring.jackson.data-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;
    // 日期序列化器
    @Bean
    public LocalDateTimeSerializer localDateTimeSerializer(){
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
    }
    // 日期反序列化器
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(){
        return builder->builder
        		.serializerByType(LocalDateTime.class,localDateTimeSerializer());
    }
}
3、Jackson注解使用
2.1、序列化注解:
  • @JsonAnyGetter 将对象Map作为属性
  • @JsonGetter 方法注解:将getter结果作为属性
  • @JsonPropertyOrder 类注解:指定序列化后属性栓
  • @JsonRawValue 序列化时将属性原样输出
  • @JsonValue 方法注解:将方法的结果序列化
  • @JsonRootName 类注解:为json加一个根属性
  • @JsonSerialize 自定义序列化器
  • @JsonInclude 类注解:序列化时排除null值
  • @JsonAppend 序列化时增加一个虚拟属性
2.2、反序列化注解:
  • @JacksonInject 注入属性
  • @JsonDeserialize 自定义反序列化器
  • @JsonAlias 反序列化别名
  • @JsonIgnoreProperties 类注解,忽略属性
2.2、序列化和反序列化共用:
  • @JsonIgnore 忽略属性
  • @JsonIgnoreType 类注解,忽略属性类型,统一变成String
  • @JsonInclude 类和属性:排除空属性
  • @JsonProperty 方法注解:设置别名
  • @JsonFormat 属性格式化,可格式化日期和金额,以及自定义格式化
  • @JsonUnwrapped 去掉外包装根节点名称
  • @JsonView 指定序列化和反序列化的视图级别
  • @JsonManagedReference 解决不同属性的依赖关系
  • @JsonBackReference 解决不同属性的依赖关系,防止循环调用
  • @JsonFilter 序列化时指定一个过滤器
  • @JsonNaming 属性明明方式设置,例如驼峰,中华线,首字母小写,首字母大写等
  • @Transient 不序列化字段
2.3 注解使用示例
@Data
public class User<T> {
	@JsonIgnore // 忽略序列化字段
    private String pid;  
    @Transient  // 不序列化字段
    private String remark;
    private Role role;
    @JsonProperty("userName")   //转换属性名称
	private String account;
    //反序列化--格式化日期
	@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
	private LocalDateTime createTime;
    //自定义序列化 
    @JsonSerialize(using = Date2LongSerialize.class)
	private Date operaterTime;
    //自定义反序列化处理
    @JsonDeserialize(using = CustomDateDeserializer.class)
    public Date eventDate;
}
2.4、jackson和xml序列化与反序列化
//(15)xml的序列化
@Data
@JacksonXmlRootElement(localName = "root")
public class RootXml {
 
    private String k1;
 
    @JacksonXmlProperty(localName = "k-2")
    private Integer k2;
 
    @JacksonXmlElementWrapper(localName = "k3")
    private Collection<String> ki;
 
    @JacksonXmlElementWrapper(localName = "k4")
    @JacksonXmlProperty(localName = "ka")
    private Collection<String> k4;
 
    @JacksonXmlElementWrapper(localName = "k5", useWrapping = false)
    private Collection<String> k5;
    
    @JacksonXmlProperty(isAttribute = true)
    private Integer k6;
    
    @Data
    public static class Value1 {
 
        @JacksonXmlText
        private String a;
    }
 
    private Value1 k7;
 
    @Data
    public static class Value2 {
 
        @JacksonXmlText(value = false)
        private String a;
    }
 
    private Value2 k8;
 
    @JacksonXmlCData(value = true) // 序列化时是否总是使用 CDATA 块
    private String k9;
}
 //反序列化
 //ReqMessage reqMessage = JacksonUtil.readValueXml(json, RootXml.class);
4、各种自定义的示例
4.1、自定义序列化器示例

// Date自定义序列化
public class CustomDateSerializer extends StdSerializer<Date> {
    private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
    public CustomDateSerializer() { this(null); } 
    public CustomDateSerializer(Class<Date> t) { super(t); }
    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider arg2) 
    	throws IOException, JsonProcessingException {
        gen.writeString(formatter.format(value));
    }
}

// LocalDateTime 自定义序列化
public class MyLocalDateTimeDeserializer  extends JsonDeserializer<LocalDateTime> {

  @Override
  public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException {
    String dateStr = parser.getText();
    DateTime dateTime = null;
    try{
      dateTime = DateUtil.parse(dateStr);
    }catch (Exception e){
      dateTime = DateUtil.parseDateTime(dateStr.replaceAll("T"," "));
    }
    LocalDateTime localDateTime = dateTime.toJdkDate().toInstant()
            .atZone(ZoneId.systemDefault()).toLocalDateTime();
    return localDateTime;
  }

  @Override
  public Class<?> handledType() {
    return LocalDateTime.class;
  }
}


4.2 自定义反序列化器
// Date反序列化器
public class CustomDateDeserializer  extends StdDeserializer<Date> { 
    private static SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
     public CustomDateDeserializer() { 
        this(null); 
    }  
    public CustomDateDeserializer(Class<?> vc) { 
        super(vc); 
    }
    @Override
    public Date deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException {         
        String date = jsonparser.getText();
        try {
            return formatter.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
}

// LocalDateTime反序列化器
public class MyLocalDateTimeDeserializer  extends JsonDeserializer<LocalDateTime> {
  @Override
  public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException {
    String dateStr = parser.getText();
    DateTime dateTime = null;
    try{
      dateTime = DateUtil.parse(dateStr);
    }catch (Exception e){
      dateTime = DateUtil.parseDateTime(dateStr.replaceAll("T"," "));
    }
    Date date = dateTime.toJdkDate();
    Instant instant = date.toInstant();
    ZoneId zoneId = ZoneId.systemDefault();
    LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
    return localDateTime;
  }
  @Override
  public Class<?> handledType() {
    return LocalDateTime.class;
  }
}

4.2 自定义过滤器
FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter",
        SimpleBeanPropertyFilter.filterOutAllExcept("name"));
5、Jackson工具类
public class JacsonUtils {
    public static final ObjectMapper MAPPER;
    static {
        MAPPER = new ObjectMapper();
        MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        MAPPER.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }
    //===============================序列化================//
    @SneakyThrows
    public static String toString(Object obj) {
        if (obj == null) return null;
        if (obj.getClass() == String.class)  return Convert.toStr(obj);
        return MAPPER.writeValueAsString(obj);
    }
    //==========================反序列化===============//
    //对象反序列化
    @SneakyThrows(value={IOException.class})
    public static <T> T toBean(String json, Class<T> tClass) {
        if(StrUtil.isEmpty(json)) return null;
        return MAPPER.readValue(json, tClass);
    }
 	//集合反序列化
    @SneakyThrows(value={IOException.class})
    public static <E> List<E> toList(String json, Class<E> eClass) {
        if(StrUtil.isEmpty(json)) return null;
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, Bean.class);
        return MAPPER.readValue(json,javaType);
    }
 	//Map集合反序列化
    @SneakyThrows(value={IOException.class})
    public static <K, V> Map<K, V> toMap(String json, Class<K> kClass, Class<V> vClass) {
        if(StrUtil.isEmpty(json)) return null;
        JavaType javaType = MAPPER.getTypeFactory()
                .constructParametricType(HashMap.class,String.class, Bean.class);
        return MAPPER.readValue(json, javaType);
    }
 	//复杂对象反序列化
    @SneakyThrows(value={IOException.class})
    public static <T> T nativeRead(String json, TypeReference<T> type) {
        if(StrUtil.isEmpty(json)) return null;
        return MAPPER.readValue(json, type);
    }
}

二、fastJson方案

1、添加依赖
<!-- fastjson -->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.1</version>
</dependency>
2、配置类
  • 一般场景下可以不需要配置类,采用默认的方式即可
@Configuration
public class FJsonConfig {
    
    @Bean
    public HttpMessageConverter configureMessageConverters() {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        config.setSerializerFeatures(
                // 可以配置不同的属性序列化方式
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.WriteNullNumberAsZero,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteNullBooleanAsFalse,
                SerializerFeature.DisableCircularReferenceDetect);

        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(Charset.forName("UTF-8"));
        List<MediaType> mediaTypeList = new ArrayList<>();
        mediaTypeList.add(MediaType.APPLICATION_JSON);
        converter.setSupportedMediaTypes(mediaTypeList);
      return converter;
    }
}
2、fastjson使用注解自定义序列化
  • @JSONField(name = “AGE”)
    • name 设置序列后别名
    • format 格式化输出日期
    • ordinal 输出排列顺序
    • serialize 是否序列化输出
    • deserialize 是否反序列化
@Data
public class Person {
    @JSONField(name = "AGE")
    private int age;
    @JSONField(name = "FULL NAME")
    private String fullName;
    @JSONField(name="DATE OF BIRTH", format="dd/MM/yyyy", ordinal = 3)
    private Date dateOfBirth;
    @JSONField(name="CREATEDATE", serialize=false)
    private Data createDate;
}
3、json工具类整理

调用时,可以直接使用fastJsonApi

  • JSON 作为fastjson的json处理入口,相当于一个工具类,提供parseObject,parseArray,toJsonString,toJsonBytes等序列化和反序列化的
  • JSONObject/JSONArray 解析后的对象或数组
  • JSONPath采用path方式获取json值
  • JSONReader json的读取器,
public class FastJsonUtil {
    private static SerializeConfig config;
		
    static {
        config = new SerializeConfig();
        config.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
        config.put(LocalDateTime.class, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
	//设置属性
    private static final SerializerFeature[] features = {
            SerializerFeature.WriteMapNullValue,
            SerializerFeature.WriteNullListAsEmpty,
            SerializerFeature.WriteNullNumberAsZero,
            SerializerFeature.WriteNullBooleanAsFalse,
            SerializerFeature.WriteNullStringAsEmpty
    };

    //=========================序列化==========================//
    /** 对象转json */
    public static String toJSON(Object object) {
        if(object==null) return null;
        return JSON.toJSONString(object, config, features);
    }
    //===================反序列化================================
    /** Json 转为 Jave Bean */
    public static <T> T toBean(String text, Class<T> clazz) {
        if(StrUtil.isEmpty(text)) return null;
        return JSON.parseObject(text, clazz);
    }
    /** json转对象数组 */
    public static Object[] toArray(String text) {
        if(StrUtil.isEmpty(text)) return null;
        return toArray(text, null);
    }
    public static <T> Object[] toArray(String text, Class<T> clazz) {
        if(StrUtil.isEmpty(text)) return null;
        return JSON.parseArray(text, clazz).toArray();
    }
    public static Map<?, ?> toMap(String json) {
        if(StrUtil.isEmpty(json)) return null;
        return JSON.parseObject(json);
    }
    public static <T> List<T> toList(String text, Class<T> clazz) {
        if(StrUtil.isEmpty(text)) return null;
        return JSON.parseArray(text, clazz);
    }
    public static Object getValueFromJson(final String json, final String key) {
        if(StrUtil.isEmpty(json)) return null;
        return JSON.parseObject(json).getString(key);
    }
}

三、GSON方案

添加依赖
<!-- 添加Gson依赖 -->
<dependency>
     <groupId>com.google.code.gson</groupId>
     <artifactId>gson</artifactId>
     <version>${gson.version}</version>
</dependency>
1、Gson注解Bean
  • @SerializedName(value = “nameB”, alternate = {“nameC”, “nameD”})
    • value 序列化别名
    • alternate 发序列化的备用名
  • @Expose(serialize = true, deserialize = false)
  • serialize 是否可以序列化
  • deserialize 是否可以反序列化
@Data
public class MyClass {
    
    @SerializedName("nameA")
    String a;
    
    @SerializedName(value = "nameB", alternate = {"nameC", "nameD"})
    String b;
    
    @Expose(serialize = true, deserialize = false)
    String c;
}
2、Gson工具类
@Configuration
@EnableWebMvc
public class GsonUtils extends WebMvcConfigurationSupport {
    
    //无参的私有构造方法
    private  GsonUtils() { }
    
    //不用创建对象,直接使用Gson.就可以调用方法
    private static Gson gson = null;
    
    //判断gson对象是否存在了,不存在则创建对象
    static {
        if (gson == null) {
            //gson = new Gson();
            gson= new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        }
    }
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.removeIf(httpMessageConverter -> 
                httpMessageConverter instanceof MappingJackson2HttpMessageConverter);
        converters.add(new GsonHttpMessageConverter());
        super.extendMessageConverters(converters);
    }
    //==============================序列化======================//
    public static String toString(Object object) {
        if(gson==null) return null;
        return gson.toJson(object);
    }
    //=============================反序列化===================//
    @SneakyThrows
    public static <T> T toBean(String gsonString, Class<T> cls) {
        if(gson==null) return null;
        return gson.fromJson(gsonString, cls);
    }
    @SneakyThrows
    public static <T> List<T> toList(String gsonString, Class<T> cls) {
        if(gson==null) return null;
        return  gson.fromJson(gsonString, new TypeToken<List<T>>() { }.getType());
    }
    @SneakyThrows
     public static <T> List<T> toList2(String json, Class<T> cls) {
         if(gson==null) return null;
         ArrayList<T> mList = new ArrayList<T>();
         JsonArray array = new JsonParser().parse(json).getAsJsonArray();
         for(final JsonElement elem : array){
             mList.add(gson.fromJson(elem, cls));
         }
         return mList;
    }
    @SneakyThrows
    public static <T> List<Map<String, T>> toListMap(String gsonString) {
        if(gson==null) return null;
        return gson.fromJson(gsonString, new TypeToken<List<Map<String, T>>>() { }.getType());
    }
    @SneakyThrows
    public static <T> Map<String, T> toMap(String gsonString) {
        if(gson==null) return null;
        return gson.fromJson(gsonString, new TypeToken<Map<String, T>>() { }.getType());
    }
    
}
四、JsonPath工具

http://www.ibloger.net/article/2329.html

添加依赖
<!--json-path工具-->
<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.2.0</version>
</dependency>
1、JSONPath的使用
  • jsonpath主要就是通过类似地址的方式直接获取对象,目前不常用,fastjson有对应的功能
相关API使用

参照jsonpath语法

public class JsonFileUtil {
    // 直接读取json
    public static void  readjson(String json,String jsonPath){
        TypeRef<List<String>> typeRef = new TypeRef<List<String>>(){};
        List<String> titles = JsonPath.parse(json).read("$.store.book[*].title", typeRef);
        List<String> authors =  JsonPath.read(json, "$.store.book[*].author",typeRef);
        Date date = JsonPath.parse(json1).read("$['date_as_long']", Date.class);
        Book book = JsonPath.parse(json).read("$.store.book[0]", Book.class);
    }
    //通过Configuration读取并解析文件,获取某个值,可以多次获取
    public static void  readConfiguration(){
        Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
        String author0 = JsonPath.read(document, "$.store.book[0].author");
    }
    public static void readContext(){
        ReadContext ctx = JsonPath.parse(json);
            List<String> authorsOfBooksWithISBN = ctx.read("$.store.book[?(@.isbn)].author");
            Configuration configuration = Configuration.defaultConfiguration();
            List<Map<String, Object>> expensiveBooks = JsonPath
                    .using(configuration)
                    .parse(json)
                    .read("$.store.book[?(@.price > 10)]", List.class);
    }
    //支持语法
    public static void readfilter(){
          List<Map<String, Object>> books =  JsonPath.parse(json).read("$.store.book[?(@.price < 10)]");
            //过滤
            Filter cheapFictionFilter = Filter.filter(
                    Criteria.where("category").is("fiction").and("price").lte(10D)
            );
            List<Map<String, Object>> books1 = JsonPath.parse(json).read("$.store.book[?]", cheapFictionFilter);
    }
}

https://www.cnblogs.com/baiqiantao/p/7512336.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值