[jackson] l'annotation de champ personnalisé complète la logique de sérialisation

arrière-plan

SpringL'outil de sérialisation par défaut JSONutilise l'adresse du projetjackson :GitHubhttps://github.com/FasterXML/jackson

Lorsque nous traitons des interactions d'interface front-end et back-end, nous pouvons avoir besoin de mettre en œuvre diverses exigences personnalisées.Cet article présente principalement des annotations personnalisées, puis effectue un traitement de logique métier sur des champs spécifiques.

Introduction à l'environnement de développement de cet article

dépendances de développement Version
Botte de printemps 3.1.2
JDK 17

Créer une nouvelle annotation

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

@Target({
    
    ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@JsonSerialize(using = PrintFieldJsonSerializer.class)
public @interface PrintField {
    
    

    Type rule() default Type.TYPE_1;

    enum Type {
    
    
        TYPE_1, TYPE_2
    }
}

Créer un nouveau JavaBean

Utiliser des annotations personnalisées sur les champs

import lombok.Builder;
import lombok.Data;

/**
 * @author tangheng
 */
@Data
@Builder
public class DemoPerson {
    
    

    @PrintField(rule = PrintField.Type.TYPE_1)
    private String name;
    @PrintField(rule = PrintField.Type.TYPE_2)
    private String email;
}

Créer un nouveau JsonSerializer

pour une logique métier personnalisée

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;

@Slf4j
@RequiredArgsConstructor
public class PrintFieldJsonSerializer extends JsonSerializer<String> {
    
    

    private final PrintField.Type rule;

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
    
    
        if(StringUtils.isBlank(value)) {
    
    
            return;
        }
        switch (rule) {
    
    
            case TYPE_1:
                log.info("hello, value: {}", value);
                break;
            default:
                log.info("rule: {}, value: {}", rule, value);
                break;
        }
        gen.writeString(value);
    }
}

Créer un nouveau AnnotationIntrospector

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.Annotated;

import java.lang.annotation.Annotation;

public class PrintFieldAnnotationIntrospector extends AnnotationIntrospector {
    
    

    @Override
    public Version version() {
    
    
        return Version.unknownVersion();
    }

    @Override
    public Object findSerializer(Annotated a) {
    
    
        PrintField ann = _findAnnotation(a, PrintField.class);
        if (ann != null) {
    
    
            return new PrintFieldJsonSerializer(ann.rule());
        }
        return null;
    }

    @Override
    public boolean isAnnotationBundle(Annotation ann) {
    
    
        if (PrintField.class.isAssignableFrom(ann.getClass())) {
    
    
            return true;
        }
        return false;
    }
}
  • Cette étape est très critique, utilisez le mécanisme Introspector de Jackson pour jouer un lien entre le précédent et le suivant.
  • Déterminez qu'il existe des annotations personnalisées sur le champ, puis utilisez le JsonSerializer personnalisé
  • Cela lie le tout ensemble

Test de l'unité

class PrintFieldJsonSerializerTest extends JsonSpringbootTestBase {
    
    

    private ObjectMapper objectMapper = new ObjectMapper();

    @SneakyThrows
    @Test
    void serialize() {
    
    
        objectMapper.setAnnotationIntrospector(new PrintFieldAnnotationIntrospector());

        DemoPerson demoPerson = DemoPerson.builder()
                .name("zhangsan")
                .email("[email protected]")
                .build();

        String testResult = objectMapper.writeValueAsString(demoPerson);
        log.info("testResult: {}", testResult);
        assertTrue(StringUtils.isNotBlank(testResult));
    }
}

Capture d'écran des résultats des tests unitaires
insérez la description de l'image ici

Résumer

  • Il existe des dizaines de millions de façons de réaliser une exigence. Pour un programmeur en quête d'exécution, étudiez le code source pour trouver la manière la plus raffinée d'atteindre l'objectif de la manière la plus simple, la meilleure en termes d'évolutivité et de maintenabilité.
  • En cas de besoin, ne vous précipitez pas pour écrire du code, étudiez le code source, ce qui peut nous aider à atteindre notre objectif avec élégance
  • Peut-être que le temps passé à étudier le code source est beaucoup plus long qu'à écrire du code, mais la récolte et le sentiment d'accomplissement sont toujours très satisfaisants
  • Même si les exigences sont finalement réalisées avec seulement quelques lignes de code, un bon programmeur ne se mesure jamais au nombre de lignes de code
  • La désérialisation de jackson peut être réalisée en se référant au même principe

Je suppose que tu aimes

Origine blog.csdn.net/friendlytkyj/article/details/132244878
conseillé
Classement