Comment utiliser l'Interface comme type de champ dans le Corps de la Requête de la classe du modèle dans l'API Rest

0

La question

Nous avons un Java SpringBoot API point de terminaison et de nous transmettre une RequestBody de NotifyMoiChanges type de classe. Dans NotifyMoiChanges modèle de la classe, nous avons un déposées qui est le type d'Interface.

Point de terminaison extrait :

@PostMapping("/notifyMOIChanges")
public ResponseEntity<Void> notifyMOIChangesPost(@RequestBody NotifyMoiChanges notifyMoiChanges) {
        logger.info("Received notifyMOIChanges request.");
        return ResponseEntity.noContent().build();
    }

RequestBody Modèle extrait:

public class NotifyMoiChanges {
  @JsonProperty("moiChanges")
  @Valid
  private List<MoiChange> moiChanges = new ArrayList<MoiChange>();
  ..... other attributes
}

public class MoiChange   {
      @JsonProperty("operation")
      private String operation = null;   //operation value can be "Type1" or "Type2"
    
      @JsonProperty("value")
      private OneOfMoiChangeValue value = null;   //value filed can be mapped with any of the OneOfMoiChangeValue Interface implentations  Type1MoiChangeValue or Type2MoiChangeValue.
    }

OneOfMoiChangeValue est une Interface qui a deux implémentations Type1MoiChangeValue & Type2MoiChangeValue.

Maintenant, quand je passe un RequestBody repose sur l '"opération" déposé données que j'ai pour cartographier le champ "valeur" du Corps de la Requête avec les implémentations d'Interface Type1MoiChangeValue ou Type2MoiChangeValue.

public interface OneOfMoiChangeValue {

}

Type1MoiChangeValue:

@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2021-11-16T11:51:46.436+05:30[Asia/Calcutta]")
public class Type1MoiChangeValue  extends ArrayList<Type2MoiChangeValue > implements OneOfMoiChangeValue {

  @Override
  public boolean equals(java.lang.Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    return true;
  }

  @Override
  public int hashCode() {
    return Objects.hash(super.hashCode());
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class Type1MoiChangeValue {\n");
    sb.append("    ").append(toIndentedString(super.toString())).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(java.lang.Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }
}

Type2MoiChangeValue:

@javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.SpringCodegen", date = "2021-11-16T11:51:46.436+05:30[Asia/Calcutta]")
public class Type2MoiChangeValue extends HashMap<String, Object> implements OneOfMoiChangeValue {

  @Override
  public boolean equals(java.lang.Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    return true;
  }

  @Override
  public int hashCode() {
    return Objects.hash(super.hashCode());
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class Type2MoiChangeValue {\n");
    sb.append("    ").append(toIndentedString(super.toString())).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(java.lang.Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }
}

Nous sommes à l'aide de jackson analyseur. Comment puis-je le faire. S'il vous plaît conseils!

interface jackson java spring
2021-11-23 07:51:37
1

La meilleure réponse

1

Vous aurez besoin de quelques modifications dans votre code et comme une conséquence dans votre corps de la requête. La première est la mise à jour OneOfMoiChangeValue avec un couple de Jackson annotations afin qu'il puisse savoir comment gérer les différents sous-types basés sur une propriété nommée operation:

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

import static com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY;
import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME;

@JsonTypeInfo(use = NAME, include = PROPERTY, property = "operation")
@JsonSubTypes({
  @JsonSubTypes.Type(value=Type1MoiChangeValue.class, name = "Type1"),
  @JsonSubTypes.Type(value=Type2MoiChangeValue.class, name = "Type2")
})
public interface OneOfMoiChangeValue {

}

Cela signifie que vous n'avez plus besoin de la operation propriété dans MoiChange:

public class MoiChange {
      @JsonProperty("value")
      private OneOfMoiChangeValue value = null;   //value filed can be mapped with any of the OneOfMoiChangeValue Interface implentations  Type1MoiChangeValue or Type2MoiChangeValue.
}

Au lieu de cela, elle doit être envoyée aux côtés de toutes les autres propriétés de OneOfMoiChangeValue, si quelque chose le long des lignes suivantes:

{
    "moiChanges": 
    [
        {
            "value": {
                "operation": "Type1",
                (...)
            }    
        },
        {
            "value": {
                "operation": "Type2",
                (...)
            }    
        },
        (...)
    ]
}
2021-11-23 14:56:57

Cela semble bon. Permettez-moi de l'essayer et de vous mettre à jour.
SuryaN

Salut @Jean , je viens de maintenant est venu de savoir que je ne peut pas modifier le corps de la requête et ajouter le champ supplémentaire "opération" à l'intérieur de la "valeur" de l'attribut que l'Req Corps est considéré comme format standard et n'avez pas la permission de les manipuler. Donc, sans ajouter un champ supplémentaire dans le corps de la requête pouvons-nous le faire?
SuryaN

Non pas que je suis au courant de. La seule option pourrait être une coutume deserializer. J'aime vraiment la façon dont les gens pensent que le logiciel est un ensemble en pierre de chose et que les changements ne peuvent pas être fait de toute façon (je sais ce n'est pas votre décision ;) ).
João Dias

Oui d'accord avec vous. :) Nous avons personnalisées deserializer dans ce cas. Je suis de nouveau pour elle. Donc, essayer d'écrire quelques si je peux le faire.
SuryaN

Salut @João Dias, j'ai écrit une coutume deserializer comme vous l'avez dit et cela a fonctionné. Aussi la suggestion que vous avez dans la réponse sera de travailler la plupart des cas on peut généralement passer le champ supplémentaire dans le json. Je suis de l'acceptation de votre solution était la bonne. Merci pour votre aide pour le résoudre :)
SuryaN

Vous êtes les bienvenus! Pensez également à ajouter vos personnalisée deserializer comme une réponse et de l'accepter ;)
João Dias

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................