Контроллер Spring Boot преобразует JSON объектов в null - PullRequest
1 голос
/ 20 июня 2020

Я создаю контроллер RESTful в Spring Boot. Метод контроллера работает, когда есть только один параметр метода. К сожалению, когда есть два параметра, значения обоих полей POJO заканчиваются нулевым значением. Буду признателен, если кто-нибудь поможет мне понять, почему. Кроме того, почему в моем коде не работает @Valid?

Контроллер

@RestController
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Slf4j
public class ParticipantController {

    @Autowired
    ParticipantServiceImpl participantService;

    @DeleteMapping(value = "/removeParticipantFromConference", consumes = "application/json")
    public String removeParticipantFromConference(@RequestBody @Valid Participant participant, @Valid Conference conference, BindingResult bindingResult) {
        log.info("Call for ParticipantController -> removeParticipantFromConference");
        log.info("Received message is {}, {}", participant, conference);

        if (bindingResult.hasErrors()) {
            log.error("bindingResult.hasErrors()");
            return "bindingResult.hasErrors()";
        }

        String resultMessage = participantService.removeParticipantFromConference(participant, conference);
        return resultMessage;
    }

JSON сообщение, отправленное с помощью Postman,

{
    "participant": {
        "fullName": "FirstName LastName",
        "dateOfBirth": "10-06-2020"
    },
    "conference": {
        "name": "testConferenceName",
        "startDateTime": "10-06-2020 10:10",
        "endDateTime": "10-06-2020 11:15",
        "conferenceRoom": {
            "name": "ConferenceRoom_1",
            "location": "Location_1",
            "maxSeats": 5
        }
    }
}

, что является регистрируется как

Received message is Participant(id=0, fullName=null, dateOfBirth=null), Conference(id=0, name=null, startDateTime=null, endDateTime=null, conferenceRoom=null, participants=[])

Все поля класса являются закрытыми и имеют геттеры.

Подобный код работает в другом контроллере, хотя @Valid по-прежнему не вызывает никаких ошибок

@RestController
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Slf4j
public class ConferenceController {

    @Autowired
    ConferenceServiceImpl conferenceService;

    @PostMapping(value = "/addConference", consumes = "application/json")
    public String addConference(@RequestBody @Valid Conference conference, BindingResult bindingResult) {
        log.info("Call for ConferenceController -> addConference. Received message is {}", conference);

        String resultMessage = conferenceService.addConference(conference);

        log.info("Sending response: " + resultMessage);
        return resultMessage;
    }
}
{
    "name": "testConferenceName",
    "startDateTime": "10-06-2020 10:10",
    "endDateTime": "10-06-2020 11:15",
    "conferenceRoom": {
        "name": "ConferenceRoom_1",
        "location": "Location_1",
        "maxSeats": 5
    }
}

Что касается @Valid, одно из полей участника -

@NotNull(message = "Participant must have name")
    @Pattern(regexp = ".+ .+")
    @Column(nullable = false)
    String fullName;

, но оно не вызывает ошибку проверки, когда полученное сообщение JSON имеет значение fullName «test».

Ответы [ 2 ]

2 голосов
/ 21 июня 2020

Вы можете получить только один @RequestBody. (Аргумент вашего кода «Conference» распознается как @ModelAttribute.) И добавьте аннотацию @Valid к полям по запросу.

@Data
public class RemoveParticipantFromConferenceRequest {
    @Valid
    private Participant participant;
    @Valid
    private Conference conference;
}

    @DeleteMapping(value = "/removeParticipantFromConference", consumes = "application/json")
    public String removeParticipantFromConference(@RequestBody @Valid RemoveParticipantFromConferenceRequest req, BindingResult bindingResult) {
        Participant participant = req.getParticipant();
        Conference conference = req.getConference();
...
1 голос
/ 21 июня 2020

requestbody всегда является объектом, вы не можете разделить его на два параметра только с помощью аннотаций ... используйте объект-оболочку следующим образом:

public class Wrapper {
  @Valid
  private Participant participant;
  @Valid
  private Conference conference;
  //....
}

и метод контроллера

public String removeParticipantFromConference(@RequestBody @Valid Wrapper wrapper...)
...