2
votes

Jackson @JsonProperty crée un nom en double

J'ai une classe

{
   "status":1,
   "message":"find 1",
   "data":[
      [
         {
            "id":4565,
            "state":"4",
            "goal":"4",
            "hobby":"hobby",
            "result":"result",
            "interest":"4",
            "student":{
               "id":0,
               "email":null,
               "password":null,
               "md5":"e22175516bc91b167e80ceae7276d83b",
               "hash":null,
               "tags":null,
               "emotions":null,
               "balance":0.0,
               "hibernateLazyInitializer":{

               }
            },
            "teacher":{
               "id":0,
               "email":null,
               "password":null,
               "md5":"e22175516bc91b167e80ceae7276d83b",
               "hash":null,
               "tags":null,
               "emotions":null,
               "balance":0.0,
               "hibernateLazyInitializer":{

               }
            },
            "robokassa":null,
            "days":[
               {
                  "id":4558,
                  "from":"10:00",
                  "to":"10:45",
                  "fselect":true,
                  "fSelect":true
               },
               {
                  "id":4559,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               },
               {
                  "id":4560,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               },
               {
                  "id":4561,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               },
               {
                  "id":4562,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               },
               {
                  "id":4563,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               },
               {
                  "id":4564,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               },
               {
                  "id":4566,
                  "from":"10:00",
                  "to":"11:00",
                  "fselect":true,
                  "fSelect":true
               },
               {
                  "id":4567,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               },
               {
                  "id":4568,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               },
               {
                  "id":4569,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               },
               {
                  "id":4570,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               },
               {
                  "id":4571,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               },
               {
                  "id":4572,
                  "from":null,
                  "to":null,
                  "fselect":false,
                  "fSelect":false
               }
            ],
            "fteacherConfirm":true,
            "fstudentConfirm":true,
            "fstudentRequest":true,
            "fStudentRequest":true,
            "fTeacherConfirm":true,
            "fStudentConfirm":true
         }
      ]
   ],
   "code":500
}

Pour sérialiser le résultat, j'utilise une classe supplémentaire

String result = HttpJsonResponse
                .createUserResponse(
                    lessons,
                    "find "+lessons.size(),
                    CODE_OK,
                    STAUS_OK
                );

Quand je sérialise la classe Lesson, j'obtiens des champs dupliqués

import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import lombok.Data;
import play.Logger;
public @Data class HttpJsonResponse<T> {


    int status;
    String message;
    List<T> data = new ArrayList<>();
    int code;

    public static <T> String createUserResponse(T data,String message,int code,int status){
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            HttpJsonResponse<T> response = new HttpJsonResponse<T>();
            response.setStatus(status);
            response.setCode(code);
            response.getData().add(data);
            response.setMessage(message);
            Logger.debug(mapper.writeValueAsString(response));
            return mapper.writeValueAsString(response);
        } catch (JsonProcessingException e) {
            Logger.error(e.toString());
            return "{\"status\":0,\"data\":[],\"code\":\"901\",\"message\":\"error\"}";     
        }
    }
}

Désolé pour cela, mais je ne peux pas ajouter plus de code dans mon message

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;

@Entity
@JsonIgnoreProperties(ignoreUnknown = true)
@Table(name = "Sheduler")
public @Data class Lesson {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", updatable = false, nullable = false)
    public int id;

    String state;
    String goal;
    String hobby;
    String result;
    String interest;

    @JsonProperty("fStudentRequest") 
    boolean fStudentRequest;
    @JsonProperty("fTeacherConfirm") 
    boolean fTeacherConfirm;
    @JsonProperty("fStudentConfirm") 
    boolean fStudentConfirm;

    @OneToOne(
            cascade = CascadeType.ALL, 
            orphanRemoval = true,
            fetch = FetchType.LAZY
    )
    @JoinColumn(name = "student_id")
    AuthorisedUser student; 

    @OneToOne(
            cascade = CascadeType.ALL, 
            orphanRemoval = true,
            fetch = FetchType.LAZY
    )
    @JoinColumn(name = "teacher_id")
    AuthorisedUser teacher; 

    @OneToMany(
            cascade = CascadeType.ALL, 
            orphanRemoval = true,
            fetch = FetchType.LAZY
    )
    @JoinColumn(name = "order_id")
    List<Robokassa> robokassa = new ArrayList<>();  

    @OneToMany(
        cascade = CascadeType.ALL, 
        orphanRemoval = true,
        fetch = FetchType.EAGER, 
        mappedBy = "sheduler"
    )
    List<LessonDays> days = new ArrayList<>();  
}

Que dois-je faire pour supprimer les doublons et obtenir champ comme fStudentConfirm


6 commentaires

comment sérialisez-vous? (j'ai compris que vous utilisiez Jackson mais comment?)


ajouter un code de sérialisation


@AlexandrLukovnikov me semble impossible. Ce n'est pas que je ne te fasse pas confiance, c'est que je n'ai jamais vu quelque chose comme ça arriver. Quelle version de Jackson utilisez-vous?


@AlexandrLukovnikov Juste testé, le résultat est parfaitement valide. Êtes-vous sûr de ne pas avoir été confus


Eh bien, cela me paraissait impossible aussi. Alors je l'ai essayé. Résultat: toutes les valeurs une seule fois comme il se doit. Quelque chose de pertinent manque dans votre message? De plus, votre sortie publiée ne ressemble pas à une sortie Jackson (pas de guillemets, pas d'accolades, pas de virgule).


Je modifie mon message. Ajouter des informations supplémentaires


3 Réponses :


2
votes

Ces noms de champs ne sont pas égaux. Il y a une différence: ft convenient eacherConfirm et fT convenient eacherConfirm . Vous utilisez probablement Lambok qui génère pour vous des getters et des setters. Dans ce scénario spécifique où les noms de champs ont une lettre étrange f Lambok crée probablement is-method comme ci-dessous:

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
mapper.setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE);

Maintenant, Jackson voit que vous avez une annotation sur la propriété et d'autres is-method qui ont un autre nom, ils génèrent deux propriétés similaires (non égales) dans JSON .

Solutions:

  1. Supprimez ce f au début ou ajoutez le mot entier commençant par f .
  2. Supprimez Lambok et générez manuellement is-method où vous avez un contrôle total sur le nom généré.
  3. Désactivez les is-methods dans Jackson comme ci-dessous:
public boolean isFstudentRequest() {
    return fStudentRequest;
}

Voir aussi:

  1. comment spécifier jackson pour n'utiliser que des champs - de préférence dans le monde


0 commentaires

1
votes

J'étais confronté à un problème similaire dans Spring Boot ce que j'ai fait a été ajouté @JsonProperty à chaque getters et setters. Cela pourrait être une solution de contournement. J'ai essayé de jouer avec le printemps "spring.jackson.mapper" mais cela n'a pas aidé.

private String Name;
@JsonProperty("Name")
public Name getName() {
    return Name;
}
@JsonProperty("Name")
public void setName(Name name) {
    Name = name;
}


0 commentaires

0
votes

Ignorez le nom de propriété généré par lombok getter:

@Entity
@JsonIgnoreProperties(ignoreUnknown = true, value={"fstudentRequest", "fstudentConfirm"})
@Table(name = "Sheduler")
public @Data class Lesson {
    // ...
}


0 commentaires