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
3 Réponses :
Ces noms de champs ne sont pas égaux. Il y a une différence: f
t convenient eacherConfirm
et f
T 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:
f
au début ou ajoutez le mot entier commençant par f
. Lambok
et générez manuellement is-method
où vous avez un contrôle total sur le nom généré. is-methods
dans Jackson
comme ci-dessous: public boolean isFstudentRequest() { return fStudentRequest; }
Voir aussi:
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; }
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 { // ... }
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