0
votes

Objet JSON vers Java avec clé aléatoire

J'essaye de convertir le JSON suivant en objet Java et je me retrouve avec UnrecognizedPropertyException.

    public class SampleTest {

       private Map<String, List<EmployeeDetails>> employeeDetails = new HashMap<String, List<EmployeeDetails>>();

       public Map<String, List<EmployeeDetails>> getEmployeeDetails() {
              return employeeDetails;
       }

       public void setEmployeeDetails(Map<String, List<EmployeeDetails>> employeeDetails) {
              this.employeeDetails = employeeDetails;
       }

   }


   public class EmployeeDetails {

       private String name;
       private String age;
       private String address;

       //Getters and Setters
   }

Ici "5214" est la clé aléatoire que j'obtiens. Je peux le cacher en modifiant un peu JSON. Mais je veux savoir s'il existe un moyen possible de convertir le JSON mentionné. J'ai même essayé avec l'extrait suivant en prenant des références.

    {
    "5214": [{
        "name": "sdsds",
        "age": "25",
        "address": null
    },
    {
        "name": "sdfds",
        "age": "26",
        "address": null
    }]
   }

Quelqu'un peut-il me guider à ce sujet?


3 Réponses :


0
votes

Vérifiez quelque chose de qui

Peut-être:

public class Data {

    // String contain the Key, for example: 5214
    Map<String, List<EmployeeDetails>> employeeDetails = 
        new HashMap<String,List<EmployeeDetails>>();

    public Data() {

    }

    @JsonAnyGetter
    public Map<String, List<EmployeeDetails>> getEmployeeDetails() {
        return employeeDetails;
    }
}


2 commentaires

Non. J'ai également essayé avec le constructeur et j'ai obtenu com.fasterxml.jackson.databind.exc.UnrecognizedPropertyExcep‌ tion: Champ non reconnu "5214"


Essayez-vous avec JsonAnyGetter @ User0234



1
votes

Utiliser la référence de type ( Importer le package Jackson pour Java )

TypeReference<Map<String, List<EmployeeDetails>>> typeReference = new TypeReference<Map<String, List<EmployeeDetails>>>()
{
};                                                    
Map<String, List<EmployeeDetails>> employeeDetails = new ObjectMapper().readValue(jsonString, typeReference);


2 commentaires

Je pense qu'il y a une faute de frappe: TypeReferenceMap > est censé être TypeReference >> .


Ouais. Vous avez raison. Merci d'avoir corrigé



0
votes

J'utiliserais un désérialiseur personnalisé avec quelques classes d'assistance. Pour rendre le code (question d'opinion je suppose) plus clair, créez l'objet de liste:

public class WrapperDeserializer extends JsonDeserializer<Wrapper> {

    private final ObjectMapper om = new ObjectMapper();
    @Override
    public Wrapper deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        TreeNode node = p.readValueAsTree();
        // This is the place for caution. You should somehow know what is the correct node
        // Here I happily assume there is just the one and first
        String fName = node.fieldNames().next();

        EmployeeDetailsList edl = om.readValue(node.get(fName).toString(),
               EmployeeDetailsList.class); 
        edl.setName(fName);
        return new Wrapper(edl);
    }

}

Ensuite, cette liste semble être à l'intérieur d'un objet, dites Wrapper :

@Getter
@RequiredArgsConstructor
@JsonDeserialize(using = WrapperDeserializer.class)
public class Wrapper {
    private final EmployeeDetailsList employeeDetailsList;
}

Il existe donc une annotation @JsonDeserializer qui gère la désérialisation de Wrapper . Il n'est pas possible de désérialiser directement les noms de champs inconnus en un type défini, nous devons donc utiliser un mécanisme comme ce désérialiseur personnalisé qui inspecte ce qui se trouve à l'intérieur de Wrapper et détermine ce qu'il faut désérialiser et comment.

Et voici comment fonctionne le désérialiseur:

@SuppressWarnings("serial")
@Getter @Setter
public class EmployeeDetailsList extends ArrayList<EmployeeDetails> {
    // this will hold the arbitrary name of list. like 5214
    private String name;
}

Veuillez le vérifier attentivement, il n'est pas parfait dans le sens de trouver toujours le bon nœud et peut-être que l'instanciation peut être faite d'autres manières meilleurs. Mais cela devrait vous donner une idée de la façon dont cela pourrait être fait.


0 commentaires