Maison > Java > javaDidacticiel > Comment résoudre les problèmes de sérialisation et de désérialisation de Json dans SpringBoot

Comment résoudre les problèmes de sérialisation et de désérialisation de Json dans SpringBoot

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
Libérer: 2023-05-12 16:07:06
avant
882 Les gens l'ont consulté

Contrôler la sérialisation/désérialisation json

1. L'utilisation de @JsonIgnoreProperties

@JsonIgnoreProperties(value = { "prop1","prop2" })
Copier après la connexion

est utilisée pour modifier la classe Pojo et ignorer les attributs spécifiés lors de la sérialisation et de la désérialisation. Un ou plusieurs attributs peuvent être ignorés.

@JsonIgnoreProperties(ignoreUnknown = true)
Copier après la connexion

Utilisé pour modifier le Pojo. classe, ignorant les propriétés qui ne peuvent pas être définies lors de la désérialisation, y compris les propriétés qui ne peuvent pas être définies dans le constructeur et qui n'ont pas de méthodes de définition correspondantes.

2 Annotation @JsonProperty

Si le nom du champ json est le même que celui de Pojo When. les noms de propriété sont incohérents, vous pouvez utiliser @JsonProperty pour annoter la méthode getter() ou setter(). Cette annotation définit le nom de propriété correspondant à json. De plus, @JsonProperty est souvent utilisé pour annoter les paramètres formels du constructeur. Dans ce cas, le constructeur L'annotation @JsonCreator doit être ajoutée.

3. Annotation @JsonCreator

Si la classe Pojo définit un constructeur avec des paramètres mais ne fournit pas de constructeur sans paramètre, une erreur sera signalée lors de la désérialisation. deux méthodes :

  • Méthode 1 : Ajouter un constructeur sans paramètre

  • Méthode 2 : Ajoutez l'annotation @JsonCreator à ce constructeur paramétré, et les paramètres doivent être annotés avec @JsonProperty.

4. Annotations avec @JsonGetter

Si le nom du champ json est incohérent avec le nom de la propriété du Pojo, vous pouvez utiliser @JsonGetter pour annoter le getter() et @JsonSetter pour annoter la méthode setter(). spécifiez un nom de propriété. Ces deux annotations peuvent être remplacées par @JsonProperty.

5 @JsonAnySetter annotation

Les noms de propriétés d'objet généraux sont déterminés, comme l'objet Car, qui a des attributs nommés tels que marque/prix. parfois, nous devons également définir certains attributs étendus. Les noms de ces attributs étendus ne sont pas encore déterminés. Map sont généralement utilisés pour stocker le K/V de ces attributs étendus. doit être désérialisé dans la classe. Dans Map, une méthode de définition K/V doit être ajoutée à la classe, et cette méthode de définition doit être annotée avec @JsonAnySetter.

public class Car {
    public String brand;
    private Map<String, String> properties;
 
    @JsonAnySetter
    public void add(String key, String value) {
        properties.put(key, value);
    }
}
Copier après la connexion

Une fois la classe ajoutée avec @JsonAnySetter, le json suivant les données peuvent être désérialisées dans Map :

{
"brand":"Benz",
"attr2":"val2",
"attr1":"val1"
}
Copier après la connexion
Copier après la connexion

6. L'annotation @JsonAnyGetter

correspond à l'annotation @JsonAnySetter Si vous souhaitez sérialiser les attributs Map K/V dans la classe en json, vous devez ajouter un @JsonAnyGetter. méthode à la classe, qui renvoie directement KV. Il suffit de mapper.

public class Car {
    public String brand;
    private Map<String, String> properties;
 
    @JsonAnyGetter
    public Map<String, String> getProperties() {
        return properties;
    }
}
Copier après la connexion

Le json sérialisé est :

{
"brand":"Benz",
"attr2":"val2",
"attr1":"val1"
}
Copier après la connexion
Copier après la connexion

7 Annotation @JsonFormat

Efface généralement le format d'heure utilisé pour la sérialisation des attributs Date/Heure.

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

8. Annotations @JsonSerialize et @JsonDeserialize

@ L'annotation JsonSerialize peut définir une fonction de sérialisation spéciale pour les attributs de classe, et l'annotation @JsonDeserialize est utilisée pour personnaliser la fonction de désérialisation pour les attributs json

Règles de sérialisation SpringBoot

  • Include .Include.ALWAYS L'attribut par défaut Include.Include.ALWAYS 默认

  • Include.NON_DEFAULT 属性为默认值不序列化

  • Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化

  • Include.NON_NULL

Include.NON_DEFAULT est la valeur par défaut et n'est pas sérialisé

Include.NON_EMPTY L'attribut est vide ("") ou NULL et n'est pas sérialisé

Include.NON_NULL L'attribut est NULL et n'est pas sérialisé

1 Paramètres globaux

/**
 * 〈返回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;
    }
}
Copier après la connexion

ou

spring.jackson.default-property-inclusion=non_null
spring:
  jackson:
    default-property-inclusion: non_null
Copier après la connexion

2. . Paramètres locaux

sur la classe d'entité ou le champ qui doit être défini. Ajoutez des annotations

@JsonInclude(Include.NON_NULL)
Copier après la connexion

3. Personnalisez la sérialisation locale

(1). Personnalisez une classe d'outil de sérialisation, qui doit implémenter StdSerializer ;

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();
 }
}
Copier après la connexion

(2) Utilisez des annotations pour agir sur les classes d'entités Le

@JsonSerialize(using = ClientObjectSerialize.class)
public class CreditBorrowerRepaymentRequestDto{
}
Copier après la connexion
(3) ci-dessus peut être utilisé sur les champs d'objets d'entité pour traiter les valeurs NULL ou convertir
@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));
 }
}
Copier après la connexion

4 Personnaliser la sérialisation globale des conversions nulles

SpringBoot renvoie. traitement de la valeur nulle dans les données Json et convertit le type de chaîne La valeur nulle est convertie en "", la valeur nulle du type de tableau de collection est convertie en [], la valeur nulle du type de données primitif est convertie en 0, la valeur nulle de type booléen est convertie sur false et la valeur nulle de l'objet entité est convertie en {}.

(1)🎜Sérialiseur de valeur nulle personnalisé🎜🎜
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();
  }
 }
}
Copier après la connexion
🎜(2)🎜Modificateur de sérialiseur🎜🎜
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); } }
Copier après la connexion
🎜(3)🎜Configurer l'entité Jackson🎜🎜
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;
 }
}
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers numéros
Obtenir : transférer des données JSON
Depuis 1970-01-01 08:00:00
0
0
0
Barre oblique inverse présente dans Json
Depuis 1970-01-01 08:00:00
0
0
0
erreur json de stockage mysql
Depuis 1970-01-01 08:00:00
0
0
0
conversion php-json
Depuis 1970-01-01 08:00:00
0
0
0
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal