Как использовать Inteface в качестве типа поля в классе модели тела запроса в Rest API

0

Вопрос

У нас есть конечная точка API Java SpringBoot, и мы передаем тело запроса типа класса NotifyMoiChanges. В классе модели NotifyMoiChanges у нас есть один файл, который является типом интерфейса.

Фрагмент конечной точки :

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

Фрагмент модели тела запроса:

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-это интерфейс, который имеет две реализации Type1MoiChangeValue и Type2MoiChangeValue.

Теперь, когда я передаю тело запроса на основе данных, поданных в "операции", я должен сопоставить поле "значение" тела запроса с любой из реализаций интерфейса Type1MoiChangeValue или 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    ");
  }
}

Значение типа 2moichangevalue:

@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    ");
  }
}

Мы используем синтаксический анализатор Джексона. Как я могу это сделать. Пожалуйста, посоветуйтесь!

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

Лучший ответ

1

Вам нужно будет внести несколько изменений в свой код и, как следствие, в тело вашего запроса. Во-первых, необходимо обновить OneOfMoiChangeValue с парой аннотаций Джексона, чтобы он мог знать, как обрабатывать различные подтипы на основе свойства с именем 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 {

}

Это означает, что вам больше не нужны operation недвижимость в 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.
}

Вместо этого он должен быть отправлен вместе со всеми другими свойствами OneOfMoiChangeValue, так что что-то вроде следующих строк:

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

Это выглядит хорошо. Позвольте мне попробовать и проинформировать вас.
SuryaN

Привет @João , я только сейчас узнал, что не могу изменить тело запроса и добавить дополнительное поле "операция" внутри атрибута "значение", поскольку тело запроса считается стандартным форматом и не имеет разрешения на его манипулирование. Итак, можем ли мы это сделать, не добавляя никаких дополнительных полей в тело запроса?
SuryaN

Насколько мне известно, нет. Единственным вариантом может быть пользовательский десериализатор. Мне очень нравится, как люди думают, что программное обеспечение-это вещь, высеченная в камне, и что изменения никоим образом не могут быть внесены (я знаю, что это не ваше решение ;) ).
João Dias

Да, согласен с вами. :) В этом случае мы должны использовать пользовательский десериализатор. Я в этом новичок. Так что пытаюсь написать что-нибудь, если смогу это сделать.
SuryaN

Привет @João Dias, я написал пользовательский десериализатор, как вы сказали, и он сработал. Также предложение, которое у вас есть в ответе, будет работать в большинстве случаев, так как мы обычно можем передать дополнительное поле в json. Я принимаю ваше решение так, как оно было правильным. Спасибо за вашу помощь в ее решении :)
SuryaN

Добро пожаловать! Подумайте также о добавлении вашего пользовательского десериализатора в качестве ответа и примите его ;)
João Dias

На других языках

Эта страница на других языках

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

Популярное в этой категории

Популярные вопросы в этой категории