ホームページ  >  記事  >  Java  >  SpringBoot での Json のシリアル化と逆シリアル化の問題を解決する方法

SpringBoot での Json のシリアル化と逆シリアル化の問題を解決する方法

WBOY
WBOY転載
2023-05-12 16:07:06721ブラウズ

コントロール json シリアル化/逆シリアル化

1. @JsonIgnoreProperties

@JsonIgnoreProperties(value = { "prop1","prop2" })

の使用法は、Pojo クラスを変更し、シリアル化および逆シリアル化中に指定されたプロパティを無視するために使用されます。1 つ以上の属性を使用できます。

@JsonIgnoreProperties(ignoreUnknown = true)

は、Pojo クラスを変更し、コンストラクターで設定できず、対応するセッター メソッドがない属性など、逆シリアル化中に設定できない属性を無視するために使用されます。

2 . @JsonProperty アノテーション

json フィールドの名前が Pojo のプロパティ名と一致しない場合、@JsonProperty を使用して getter() または setter() メソッドにアノテーションを付けることができます。このアノテーションは、対応する json を設定しますまた、@JsonProperty はコンストラクターの仮パラメータにアノテーションを付けるためによく使用されますが、このとき、コンストラクターには @JsonCreator.

3 のアノテーションを付ける必要があります。クラス定義には Parameter コンストラクターがありますが、パラメーターのないコンストラクターが提供されていない場合は、逆シリアル化中にエラーが報告されます。方法は 2 つあります:

    方法 1: パラメーターのないコンストラクターを追加する
  • 方法 2: @JsonCreator アノテーションをこのパラメーター化されたコンストラクターに追加します。パラメーターには @JsonProperty のアノテーションを付ける必要があります。
  • 4. @JsonSetter および @ JsonGetter アノテーション

json フィールドの名前が Pojo のプロパティ名と一致しない場合は、@JsonGetter を使用して getter() メソッドに注釈を付け、@JsonSetter を使用して setter() メソッドに注釈を付けることができます。注釈はプロパティ名を指定できます。どちらの注釈も @JsonProperty.

5 に置き換えることができます。 @JsonAnySetter 注釈

一般に、オブジェクトのプロパティ名は Car オブジェクトなどのように決定されます。ブランド/価格などの名前付き属性ですが、場合によっては、Car オブジェクトのいくつかの拡張属性も設定する必要があります。これらの拡張属性の名前はまだ決定されていません。通常、Map05ad6303f369fc4ccec4412db2772d19 は、これらの K/ を格納するために使用されますV. json データ内のこれらの属性をクラスのマップに逆シリアル化するには、K/V セッター メソッドをクラスに追加する必要があり、このセッター メソッドには @JsonAnySetter.

public class Car {
    public String brand;
    private Map<String, String> properties;
 
    @JsonAnySetter
    public void add(String key, String value) {
        properties.put(key, value);
    }
}
# の注釈が付けられている必要があります。 ## @JsonAnySetter を使用してクラスを追加すると、次の json データをマップに逆シリアル化できます:

{
"brand":"Benz",
"attr2":"val2",
"attr1":"val1"
}

6. @JsonAnyGetter アノテーション

は @JsonAnySetter アノテーションに対応します。クラスを変換したい Map K/V 属性を json にシリアル化するには、@JsonAnyGetter メソッドをクラスに追加する必要があります。このメソッドは KV マップを直接返すことができます。

public class Car {
    public String brand;
    private Map<String, String> properties;
 
    @JsonAnyGetter
    public Map<String, String> getProperties() {
        return properties;
    }
}

シリアル化された json は次のとおりです:

{
"brand":"Benz",
"attr2":"val2",
"attr1":"val1"
}

7. @JsonFormat アノテーション

通常は、日付/時刻プロパティのシリアル化に使用される時刻形式をクリアします。

public class Event {
    public String name;
 
    @JsonFormat(
      shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
    public Date eventDate;
}

8.@JsonSerialize および @JsonDeserialize アノテーション

@JsonSerialize アノテーション クラス属性に特別なシリアル化関数を設定できます。 @JsonDeserialize アノテーションは、json 属性の逆シリアル化関数をカスタマイズするために使用されます。

SpringBoot シリアル化ルール

#Include.Include.ALWAYS
    Default
  • Include.NON_DEFAULT
  • 属性はデフォルト値であり、シリアル化されません
  • Include.NON_EMPTY
  • 属性が空 ("") または NULL の場合、シリアル化されません。 NON_NULL
  • 属性が NULL の場合、シリアル化されません

    1. グローバル設定
  • /**
     * 〈返回json空值去掉null和""〉 〈功能详细描述〉
     * 
     * @author gogym
     * @version 2017年10月13日
     * @see JacksonConfig
     * @since
     */
    @Configuration
    public class JacksonConfig
    {
        @Bean
        @Primary
        @ConditionalOnMissingBean(ObjectMapper.class)
        public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder)
        {
            ObjectMapper objectMapper = builder.createXmlMapper(false).build();
            // 通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化
            // Include.Include.ALWAYS 默认
            // Include.NON_DEFAULT 属性为默认值不序列化
            // Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,则返回的json是没有这个字段的。这样对移动端会更省流量
            // Include.NON_NULL 属性为NULL 不序列化,就是为null的字段不参加序列化
            //objectMapper.setSerializationInclusion(Include.NON_EMPTY);
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
            return objectMapper;
        }
    }
  • または

    spring.jackson.default-property-inclusion=non_null
    spring:
      jackson:
        default-property-inclusion: non_null
    2. ローカル設定設定が必要なエンティティ クラスまたはフィールドの設定

    アノテーションの追加
  • @JsonInclude(Include.NON_NULL)
3. ローカル シリアル化のカスタマイズ

(1)、シリアル化ツール クラスのカスタマイズStdSerializer8742468051c85b06f0a0af9e3e506b5c または JsonSerializer8742468051c85b06f0a0af9e3e506b5c

public class ClientObjectSerialize extends JsonSerializer<CreditBorrowerRepaymentRequestDto>{
 @Override
 public void serialize(CreditBorrowerRepaymentRequestDto dto, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
 
  jsonGenerator.writeStartObject();
  try {
   Field[] fields = dto.getClass().getDeclaredFields();
   for (Field field : fields) {
    field.setAccessible(true);
    if(null == field.get(dto)){
     continue; 
    }
    jsonGenerator.writeFieldName(field.getName());
    jsonGenerator.writeObject(field.get(dto));
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
  jsonGenerator.writeEndObject();
 }
}

(2) アノテーションを使用してエンティティ クラスに作用する

@JsonSerialize(using = ClientObjectSerialize.class)
public class CreditBorrowerRepaymentRequestDto{
}

(3) エンティティ オブジェクト フィールドに作用したり、NULL 値を処理したり、変換

@JsonSerialize(using = ClientStringSerialize.class)
private String name;
 
@JsonSerialize(using = ClientDtaeSerialize.class)
private Date date;
public class ClientStringSerialize extends JsonSerializer<String> {
 
 @Override
 public void serialize(String string, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
 
  if(string == null){
   jsonGenerator.writeString(string + "[NULL]");
  }else{
   jsonGenerator.writeString(string);
  }
 }
}
 
public class ClientDtaeSerialize extends JsonSerializer<Date> {
 @Override
 public void serialize(Date createDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
  jsonGenerator.writeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(createDate));
 }
}

4. カスタマイズ グローバル null 変換シリアル化

SpringBoot は Json データで null 値処理を返し、文字列型の null 値を "" に変換し、コレクション配列型の null 値を [] に変換し、元のデータ型の null 値を 0 に変換し、Boolean 型の null 値を false に変換し、エンティティ オブジェクトの null 値を {} に変換します。

(1)

カスタム null 値シリアル化プロセッサ

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
/**
 * 自定义null值序列化处理器
 */
public class CustomizeNullJsonSerializer {
 
 /**
  * 处理数组集合类型的null值
  */
 public static class NullArrayJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator, 
    SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeStartArray();
   jsonGenerator.writeEndArray();
  }
 }
 
 /**
  * 处理字符串类型的null值
  */
 public static class NullStringJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator, 
    SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeString("");
  }
 }
 
 /**
  * 处理数值类型的null值
  */
 public static class NullNumberJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator, 
        SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeNumber(0);
  }
 }
 
 /**
  * 处理boolean类型的null值
  */
 public static class NullBooleanJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator, 
        SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeBoolean(false);
  }
 }
 
 /**
  * 处理实体对象类型的null值
  */
 public static class NullObjectJsonSerializer extends JsonSerializer<Object> {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator, 
        SerializerProvider serializerProvider) throws IOException {
   jsonGenerator.writeStartObject();
   jsonGenerator.writeEndObject();
  }
 }
}

(2)

シリアライザー修飾子

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import java.util.Collection;
import java.util.List;
 
/**
 * <pre class="brush:php;toolbar:false">
 * 此modifier主要做的事情为:
 * 1.当序列化类型为数组集合时,当值为null时,序列化成[]
 * 2.String类型值序列化为""
 *
 * 
*/ public class MyBeanSerializerModifier extends BeanSerializerModifier { @Override public List changeProperties(SerializationConfig config, BeanDescription beanDesc, List beanProperties) { // 循环所有的beanPropertyWriter for (int i = 0; i < beanProperties.size(); i++) { BeanPropertyWriter writer = beanProperties.get(i); // 判断字段的类型,如果是数组或集合则注册nullSerializer if (isArrayType(writer)) { // 给writer注册一个自己的nullSerializer writer.assignNullSerializer(new CustomizeNullJsonSerializer.NullArrayJsonSerializer()); } if (isStringType(writer)) { writer.assignNullSerializer(new CustomizeNullJsonSerializer.NullStringJsonSerializer()); } } return beanProperties; } /** * 是否是数组 */ private boolean isArrayType(BeanPropertyWriter writer) { Class clazz = writer.getType().getRawClass(); return clazz.isArray() || Collection.class.isAssignableFrom(clazz); } /** * 是否是String */ private boolean isStringType(BeanPropertyWriter writer) { Class clazz = writer.getType().getRawClass(); return CharSequence.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz); } /** * 是否是数值类型 */ private boolean isNumberType(BeanPropertyWriter writer) { Class clazz = writer.getType().getRawClass(); return Number.class.isAssignableFrom(clazz); } /** * 是否是boolean */ private boolean isBooleanType(BeanPropertyWriter writer) { Class clazz = writer.getType().getRawClass(); return clazz.equals(Boolean.class); } }

(3)

ジャクソン エンティティの構成

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
 
/**
 * 配置Jackson实体
 */
@Configuration
public class JacksonConfig {
 @Bean
 @Primary
 @ConditionalOnMissingBean(ObjectMapper.class)
 public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
  ObjectMapper objectMapper = builder.createXmlMapper(false).build();
  /** 为objectMapper注册一个带有SerializerModifier的Factory */
  objectMapper.setSerializerFactory(objectMapper.getSerializerFactory()
    .withSerializerModifier(new MyBeanSerializerModifier()));
 
  SerializerProvider serializerProvider = objectMapper.getSerializerProvider();
  serializerProvider.setNullValueSerializer(new CustomizeNullJsonSerializer
 .NullObjectJsonSerializer());
  return objectMapper;
 }
}

以上がSpringBoot での Json のシリアル化と逆シリアル化の問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。