[JAVA] Correspond à une propriété dont le type devient un tableau lorsqu'il est vide à l'aide de JsonDeserializer

Aperçu

Il existe une API qui renvoie JSON avec une propriété de type objet s'il existe une valeur et un type de tableau s'il est vide, et par défaut les types ne correspondent pas et ne peuvent pas être liés à la classe.

Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `net.yotama.sample.resource.Resource$Member` out of START_ARRAY token
 at [Source: (String)"{"member": []}"; line: 1, column: 12](through reference chain: net.yotama.sample.resource.Resource["member"])

Utilisez `` JsonDeserializer '' de Jackson et remplacez-le par null quand il s'agit d'un tableau afin qu'il puisse être lié à une classe de ressources.

Réponse JSON supposée

S'il y a une valeur

{
    "member": {
        "name": "yotama"
    }
}

S'il n'y a pas de valeur

{
    "member": []
}

environnement

la mise en oeuvre

Classe de ressources

Resource.java


package net.yotama.sample.resource;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.Value;

import java.io.IOException;

@Value
public class Resource {
    @JsonDeserialize(using = MemberDeserializer.class)
    Member member;

    @Value
    public static class Member {
        String name;
    }

    public static class MemberDeserializer extends JsonDeserializer<Member> {
        private ObjectMapper objectMapper = new ObjectMapper();

        @Override
        public Member deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
            TreeNode treeNode = p.getCodec().readTree(p);
            return treeNode.isObject() ? objectMapper.readValue(treeNode.toString(), Member.class) : null;
        }
    }
}

lombok.config


#J'utilise Lombok pour plus de simplicité,
# 1.16.Utilisé par Jackson à partir de 20@ConstructorProperties ne sera pas affecté, donc définissez-le provisoirement
lombok.anyConstructor.addConstructorProperties=true

Contrôle de fonctionnement

package net.yotama.sample.resource;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;

import java.io.IOException;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

@RunWith(Theories.class)
public class ResourceTest {
    private ObjectMapper objectMapper = new ObjectMapper();

    @DataPoints
    public static Fixture[] data = {
            new Fixture("{\"member\": []}", new Resource(null)),
            new Fixture("{\"member\": null}", new Resource(null)),
            new Fixture("{\"member\": {\"name\": \"hoge\"}}", new Resource(new Resource.Member("hoge"))),
    };

    @Theory
    public void test(Fixture fixture) throws IOException {
        assertThat(objectMapper.readValue(fixture.json, Resource.class), is(fixture.expected));
    }

    @RequiredArgsConstructor
    public static class Fixture {
        final String json;
        final Resource expected;
    }
}

Recommended Posts

Correspond à une propriété dont le type devient un tableau lorsqu'il est vide à l'aide de JsonDeserializer
Une valeur nulle est entrée lors de l'affectation à un tableau
Comment afficher la valeur lorsqu'il y a un tableau dans le tableau
Dupliquer un objet à l'aide d'un type générique
Obtenez le type d'un élément d'un tableau pour déterminer s'il s'agit d'un tableau
[Java] Comment convertir un élément d'un tableau de type String en type Int
Je souhaite établir une connexion lorsqu'une base de données est créée à l'aide de Spring et MyBatis
Comment utiliser un tableau pour la clé TreeMap
Un mémorandum lors de la tentative de création d'une interface graphique à l'aide de JavaFX
[Non résolu] Une exception se produit lorsqu'une connexion SSH est exécutée à l'aide de JSch à partir d'une application Java 6.
Une erreur commise lors de l'affichage d'une image à l'aide du stockage actif
Comment changer une chaîne dans un tableau en un nombre dans Ruby
Initialisation avec une chaîne vide vers une instance de type Java String
Comment générer des valeurs de tableau sans utiliser d'instruction for
Convertir un tableau potentiellement nul en flux
Patch Monkey pour renvoyer l'heure actuelle lorsqu'une chaîne vide est spécifiée dans Time.parse de Ruby