Ako používať Rozhranie ako typ poľa v Žiadosti Tela model triedy v Zvyšok API

0

Otázka

Máme Java SpringBoot API koncový bod a sme prejsť RequestBody z NotifyMoiChanges typ triedy. V NotifyMoiChanges model triedy máme jednu podal, ktoré je typ Rozhrania.

Koncový bod úryvok :

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

RequestBody Model úryvok:

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 je Rozhranie, ktoré má dve implementácie Type1MoiChangeValue & Type2MoiChangeValue.

Teraz, keď som prejsť RequestBody založené na "operáciu" podal údaje, ktoré som sa zmapovať "hodnota" oblasti Žiadosti Tela s niektorou z Rozhranie implementácie Type1MoiChangeValue alebo 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    ");
  }
}

Sme pomocou jackson parser. Ako môžem to urobiť. Prosím o radu!

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

Najlepšiu odpoveď

1

Budete musieť na pár zmien vo vašom kóde a ako dôsledok vašej žiadosti tela. Prvý je na aktualizáciu OneOfMoiChangeValue s pár Jackson anotácie tak, že to môže vedieť, ako zvládnuť rôzne subtypes založené na majetok s názvom 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 {

}

To znamená, že už nemusíte operation majetku v 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.
}

Namiesto toho, to musí byť zaslaný spolu všetky ostatné vlastnosti OneOfMoiChangeValuetak niečo spolu nasledujúce riadky:

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

To vyzerá dobre. Skúsim to ja a aktualizovať.
SuryaN

Ahoj @Joao , len som sa teraz dozvedel som sa nemôže zmeniť, žiadosť tela a pridať ďalšie pole 'prevádzka' vnútri 'hodnota' atribút ako Req Telo je považovaný za štandardný formát a nebudete mať povolenie na manipuláciu s ním. Takže bez pridania akýchkoľvek dodatočných v oblasti žiadosti tela, môžeme to urobiť?
SuryaN

Nie, že by som si vedomý. Jediná možnosť by mohla byť vlastné deserializer. Som naozaj rád, ako si ľudia myslia, že softvér je vytesané do kameňa vec a že zmeny nemožno urobiť akýmkoľvek spôsobom (viem, že to nie je vaše rozhodnutie ;) ).
João Dias

Áno, súhlasím s tebou. :) Máme používať vlastné deserializer v tomto prípade. Som nový na to. Tak sa snažia písať niektorých ak môžem to urobiť.
SuryaN

Ahoj @Joao Dias, som napísal vlastný deserializer, ako ste povedal, a fungovalo to. Tiež návrh máte v odpovedi bude pracovať väčšine prípadov, ako môžeme všeobecne prejsť extra oblasti v json. Ja som prijíma svoje riešenie, ako to bolo správne. Vďaka za vašu pomoc pri riešení to :)
SuryaN

Rado sa stalo! Zvážte tiež pridať svoje vlastné deserializer ako odpoveď, a to prijať ;)
João Dias

V iných jazykoch

Táto stránka je v iných jazykoch

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