如何在 Rest API 中的 Request Body 模型 class 中将接口用作字段类型
How to use Inteface as a field type in Request Body model class in Rest API
我们有一个 Java SpringBoot API 端点,我们传递了一个 NotifyMoiChanges class 类型的 RequestBody。在 NotifyMoiChanges 模型 class 中,我们有一个字段是接口类型。
端点片段:
@PostMapping("/notifyMOIChanges")
public ResponseEntity<Void> notifyMOIChangesPost(@RequestBody NotifyMoiChanges notifyMoiChanges) {
logger.info("Received notifyMOIChanges request.");
return ResponseEntity.noContent().build();
}
RequestBody 模型片段:
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。
现在,当我根据 'operation' 提交的数据传递 RequestBody 时,我必须将 Request Body 的 'value' 字段映射到任何接口实现 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 ");
}
}
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 ");
}
}
我们正在使用 jackson 解析器。我该怎么做。请指教!
您需要对代码进行一些更改,因此需要对请求正文进行更改。第一个是用几个 Jackson 注释更新 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 {
}
这意味着您不再需要 MoiChange
中的 operation
属性:
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",
(...)
}
},
(...)
]
}
我们有一个 Java SpringBoot API 端点,我们传递了一个 NotifyMoiChanges class 类型的 RequestBody。在 NotifyMoiChanges 模型 class 中,我们有一个字段是接口类型。
端点片段:
@PostMapping("/notifyMOIChanges")
public ResponseEntity<Void> notifyMOIChangesPost(@RequestBody NotifyMoiChanges notifyMoiChanges) {
logger.info("Received notifyMOIChanges request.");
return ResponseEntity.noContent().build();
}
RequestBody 模型片段:
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。
现在,当我根据 'operation' 提交的数据传递 RequestBody 时,我必须将 Request Body 的 'value' 字段映射到任何接口实现 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 ");
}
}
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 ");
}
}
我们正在使用 jackson 解析器。我该怎么做。请指教!
您需要对代码进行一些更改,因此需要对请求正文进行更改。第一个是用几个 Jackson 注释更新 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 {
}
这意味着您不再需要 MoiChange
中的 operation
属性:
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",
(...)
}
},
(...)
]
}