У меня есть список POST запросов, где тела запросов очень похожи
{
"entity":{
"type":"Nissan"
"parts":{
"Nissan_unique_content1":"value",
"Nissan_unique_content2":"value"
}
}
"updateDate":"Date..."
}
{
"entity":{
"type":"Ford"
"parts":{
"Ford_unique_content1":"value",
"Ford_unique_content2":"value",
"Ford_unique_content3":"value"
}
}
"updateDate":"Date..."
}
У меня универсал RequestBody
public class RequestBody<T>{
EntityBody<T> entity;
Date updateDate;
}
public class EntityBody<T>{
String type;
T parts;
}
В моем посте Controller у меня есть метод как
@RequestMapping(value = "/{type}")
public ResponseEntity<?> create(
@PathVariable(value = "type") String type,
@RequestBody RequestBody<T> body) {
...
}
В любом случае, общий тип T может быть назначен в зависимости от типа?
В этом случае мне не нужно было бы создавать несколько методов создания, иначе мне нужно создать несколько методов, например
@RequestMapping(value = "/nissan")
public ResponseEntity<?> createNissan(
@RequestBody RequestBody<NissanContent> body) {
...
}
@RequestMapping(value = "/ford")
public ResponseEntity<?> createFord(
@RequestBody RequestBody<Ford> body) {
...
}
какие ненужные повторы.




Это можно сделать с помощью аннотации @JsonTypeInfo.
Например:
Определите объекты в соответствии с различными структурами под ключом «части»:
class NissanParams {
@JsonProperty("Nissan_unique_content1")
private String nissanUniqueContent1;
@JsonProperty("Nissan_unique_content2")
private String nissanUniqueContent2;
// getters + setters
}
В EntityBody удалите поле type и добавьте аннотации:
public class EntityBody<T> {
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
@JsonSubTypes({ @JsonSubTypes.Type(value = NissanParams.class, name = "Nissan")})
private T parts;
}
И будет один метод контроллера:
@PostMapping(path = "{make}",
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE)
public RequestBody<Object> create(@PathVariable("make") String make,
@org.springframework.web.bind.annotation.RequestBody RequestBody<Object> body) {
// please change the name of "RequestBody" entity, in order to avoid name clash with the annotation
}
Вы можете использовать аннотации JsonTypeInfo и JsonSubTypesJackson. Ваша модель может выглядеть так:
class EntityBody {
private Car parts;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type", include = JsonTypeInfo.As.EXTERNAL_PROPERTY)
@JsonSubTypes({
@JsonSubTypes.Type(name = "Ford", value = Ford.class),
@JsonSubTypes.Type(name = "Nissan", value = Nissan.class)
})
public Car getParts() {
return parts;
}
}
Как видите, вам не нужно type имущество. Его прочитает Jackson, чтобы узнать тип автомобиля. Я создал Car базовый класс/интерфейс, но вам не нужно этого делать.
Ваш метод POST может выглядеть так:
@RequestMapping(value = "/cars", method = RequestMethod.POST)
public ResponseEntity<?> create(@RequestBody RequestPayload body) {
logger.info(body.toString());
return ResponseEntity.ok("OK");
}
Здесь не нужно PathVariable.
Вы можете использовать jackson для сопоставления json с объектами (baeldung.com/jackson-inheritance). На стороне java вы можете использовать шаблон посетителя.