Cómo utilizar la Interfaz como un tipo de campo en la Solicitud de modelo de Cuerpo de la clase de la API de Rest

0

Pregunta

Tenemos un Java SpringBoot extremo de API y pasamos un RequestBody de NotifyMoiChanges tipo de clase. En NotifyMoiChanges de la clase del modelo que hemos presentado, que es el tipo de Interfaz.

Extremo fragmento de código :

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

RequestBody Modelo fragmento de código:

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 es una Interfaz que tiene dos implementaciones Type1MoiChangeValue & Type2MoiChangeValue.

Ahora cuando me pase un RequestBody basado en la 'operación presentados los datos que tengo para asignar el campo "valor" de la Solicitud de Cuerpo con alguna de las implementaciones de Interfaz Type1MoiChangeValue o 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    ");
  }
}

Estamos utilizando jackson analizador. ¿Cómo puedo hacerlo. Por favor, consejos!

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

Mejor respuesta

1

Usted necesitará un par de cambios en el código y, como consecuencia, en su solicitud de cuerpo. La primera es la actualización de OneOfMoiChangeValue con un par de Jackson anotaciones de modo que se puede saber cómo manejar los diferentes subtipos basados en una propiedad denominada 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 {

}

Esto significa que usted ya no necesita la operation propiedad en 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.
}

En su lugar, debe ser enviado junto con todas las demás propiedades de OneOfMoiChangeValue, algo así a lo largo de las siguientes líneas:

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

Esto se ve bien. Déjame intentarlo y actualización.
SuryaN

Hola @Juan , acabo de vino a saber que no puedo cambiar el cuerpo de solicitud y agregar el campo extra 'operación' dentro de la 'valor' atributo como el de Req Cuerpo es considerado como formato estándar y no tienen permiso para manipularlo. Así, sin añadir ningún campo adicional en el cuerpo de solicitud podemos hacerlo?
SuryaN

No que yo sepa. La única opción podría ser una costumbre deserializer. Me gusta mucho cómo la gente piensa que el software es un conjunto en piedra cosa y que los cambios no se puede hacer en cualquier forma (ya sé que este no es su decisión ;) ).
João Dias

Sí de acuerdo con usted. :) Tenemos que usar personalizado deserializer en este caso. Soy nuevo en esto. Así que tratando de escribir algunas si que puedo hacerlo.
SuryaN

Hola @João Dias, he escrito una costumbre deserializer como usted ha dicho y ha funcionado. También la sugerencia de que usted tiene en la respuesta funcionará en la mayoría de los casos, como podemos pasar el campo adicional en el json. Estoy aceptando su solución es correcta. Gracias por su ayuda para resolverlo :)
SuryaN

Usted es bienvenido! Considerar también la posibilidad de añadir su costumbre deserializer como una respuesta y aceptarlo ;)
João Dias

En otros idiomas

Esta página está en otros idiomas

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