Table des matières
arrière-plan
Spring
L'outil de sérialisation par défaut JSON
utilise l'adresse du projetjackson
:GitHub
https://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
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