Sprawdzenie przesyłanych pól

0

Mam endpoint który przyjmuje POST z name, surname, phone, email

	@PostMapping
	public Integer add(@Valid @RequestBody PersonDTO personDTO) {
		//addPerson(personDTO);
	}
	
	public class PersonDTO {
		@NotEmpty
		String name;
		
		@NotEmpty
		String surname;

		@NotEmpty
		Integer phone;

		@NotEmpty
		String email;
	}
	

I teraz chciałbym miec możliwość aby ten kto poda phone nie musiał podawać email.
Wiem że mogę zdjąc @NotEmpty z email i sprawdzać juz sobie potem np. w ciele metody add
ale czy intnieje możliwość aby zachować adnotacje w PersonDTO (w ogóle nie ruszać) i posłuzyć sie dodatkowym, drugim DTO lub coś w tym stylu?
Czy istnieje jakis inny sposób rozwiązania tego problemu aby nie ruszać PersonDTO?
Jednym słowem walidacja tego co przyjdzie w zależności co przyjdzie :)

0

Można wyekstraktować pola phone oraz email do nowej klasy Contact, i wtedy juz pole Contact contact byłoby oznaczone jako @NotNull, a sprawdzenie, że przynajmniej jedno zostało podane, możesz zrobić sam w konstruktorze klasy Contact - dzięki temu, możesz np zrobić klasę Contact niemutowalną, jako tzw. Value Object.

0

@Pinek: Nie za bardzo bo wtedy bym miał coś takiego:

{name: "blablabla", surname: "testtesttest", contact: { ... } }

a tak nie chce, pola musza być wysłane w formie

 {name: "blablabla", surname: "testtesttest", phone: 1234, email: "[email protected]" }
0

No to możesz w PersonDTO w ogóle walidację pominąć, potraktować to jako zwykłe DTO bez żadnej logiki, a potem przemapować to po prostu w Person, które już te ograniczenia ma, i może mieć inną strukturę.

0

@Pinek: to wiem, ale tak jak pisałem, czy nie da się tego zrobic bez ruszania PersonDTO?

0

Nie nie jest to tak proste musisz usunąć @NotEmpty. Musisz, utworzyć własny validator na poziomie klasy (PersonDTO), najlepiej, który generycznie sprawdzi za pomocą systemu refleksji czy z zadanych pól w adnotacji przynajmniej jeden nie jest null. Przykład

@AtLeastOneIsNotEmpty(fields = {"phoneNumber", "email"})
public PersonDto {
  private String phoneNumber;
  private String email;
}
0

słabo, myślałem, że istnieje jakiś myk inny który by na to pozwolił (nie ruszać PersonDTO)

4

Nie programuj w adnotacjach tylko pisz pan walidator

0

OK a jak zrobić aby przekazać wartość pola email jeśli adnotacja będzie przy phone

      @MyCustomValid(field = "email")
        Integer phone;

        String email;

Mam tak ale otrzymuje słowo "email" zamiast wartości...

0

Nie da się mając na poziomie phone musisz ten walidator wynieść na poziom klasy wtedy jeżeli dobrze pamiętam przy implementacji interfejsu wygląda to jakoś tak:

public class CustomValidator implements Validator<PersonDto> {

   public boolean isValid(PersonDto personDto) {
      return personDto.getPhone() != null || personDto.getEmail() != null; //oczywiscie systemem refleksji tutaj 
  }
}

jak zrobisz na phone to masz

public class CustomValidator implements Validator<Integer> {

   public boolean isValid(Integer phone) {
     
  }
}

Zobacz, gdzie dałem adnotacje w poście powyżej

1 użytkowników online, w tym zalogowanych: 0, gości: 1