Wenn Sie eine Handlerklasse mit [@ControllerAdvice] vorbereiten (https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/ControllerAdvice.html) Die Behandlung von Validierungsfehlern jedes Controllers kann sofort behandelt werden.
Java 11
SpringBoot 2.3.3
Im Folgenden wird der REST-Controller erläutert, der eine Liste von Benutzern durch Angabe von Suchparametern erfasst. Die Eingabevalidierung der Anforderung wird bereitgestellt, und wenn ein Validierungsfehler erkannt wird, wird ein 400-Fehler zusammen mit einem vorbestimmten Antworttext zurückgegeben.
Fügen Sie dem Argument "@ Validated" hinzu, damit die Validierung durchgeführt wird. Die Behandlung zum Zeitpunkt des Fehlers wird hier nicht besonders durchgeführt.
@RestController
@RequiredArgsConstructor
public class UserController {
@NonNull
private final UserService userService;
@NonNull
private final GetUsersQueryValidator getUsersQueryValidator;
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.addValidators(getUsersQueryValidator);
}
/**
*Erhalten Sie Benutzerinformationen, indem Sie Suchbedingungen angeben
*
* @param getUsersQuery Suchkriterien Abfrageparameter
* @zurückgegeben Gesuchte Benutzerinformationen
*/
@GetMapping(value = "/users")
ResponseEntity<List<UserDto>> getUsers(@Validated GetUsersQuery getUsersQuery) {
SearchUsersCondition searchUsersCondition = new SearchUsersCondition();
searchUsersCondition.setName(getUsersQuery.getName());
searchUsersCondition.setLowerLimitAge(getUsersQuery.getLowerLimitAge());
searchUsersCondition.setUpperLimitAge(getUsersQuery.getUpperLimitAge());
return ResponseEntity.ok(userService.searchUsers(searchUsersCondition));
}
}
Die Klasse, an die die Abfrageparameter der Anforderung gebunden sind. "@ NotBlank" und "@ NotNull" werden zu jedem Feld hinzugefügt, so dass eine Einzeltermvalidierung durchgeführt wird.
/**
*Abfrageparameter, die Benutzersuchbedingungen angeben
*/
@Data
public class GetUsersQuery {
/**
*Nutzername
*/
@NotBlank
private String name;
/**
*Mindestalter
*/
@NotNull
private Integer lowerLimitAge;
/**
*Maximales Alter
*/
@NotNull
private Integer upperLimitAge;
}
Ein Fehler tritt auf, wenn das untere Grenzalter des Abfrageparameters das obere Grenzalter überschreitet.
/**
* {@link GetUsersQuery}Korrelationsvaridaten
*/
@Component
public class GetUsersQueryValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return GetUsersQuery.class.isAssignableFrom(clazz);
}
/**
*Validierungsimplementierung
*
* @param target Validierungsziel
* @Parameterfehler Erkannte Fehler
*/
@Override
public void validate(Object target, Errors errors) {
//Eine Korrelationsvalidierung wird nicht durchgeführt, wenn ein einzelner Termfehler entweder im oberen Grenzalter oder im unteren Grenzalter auftritt.
if (errors.hasFieldErrors("lowerLimitAge") || errors.hasFieldErrors("upperLimitAge")) {
return;
}
GetUsersQuery getUsersQuery = GetUsersQuery.class.cast(target);
int lowerLimitAge = getUsersQuery.getLowerLimitAge();
int upperLimitAge = getUsersQuery.getUpperLimitAge();
//Wenn das Alter der Obergrenze das Alter der Untergrenze nicht überschreitet, tritt ein Fehler auf.
if (lowerLimitAge >= upperLimitAge) {
errors.reject("reverseLimitAge");
}
}
}
Wenn ein Fehler auftritt, wird ein Objekt dieses Typs im Antworttext gespeichert.
/**
*Fehlerinformationen, die im Anforderungshauptteil festgelegt werden sollen
*/
@Data
public class ApiError implements Serializable {
private static final long serialVersionUID = 1L;
private String message;
}
Bereiten Sie eine Ausnahmebehandlungsklasse mit @ ControllerAdvice
vor, wie unten gezeigt.
/**
*Handler für Ausnahmen, die auf dem Controller ausgelöst wurden
*/
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@Autowired
MessageSource messageSource;
/**
* {@link BindException}Handhabung
*
* @param bindException {@link BindException}
* @param httpHeaders {@link HttpHeaders}
* @param httpStatus {@link HttpStatus}
* @param webRequest {@link WebRequest}
* @Antwort an Client zurückgeben
*/
@Override
protected ResponseEntity<Object> handleBindException(
BindException bindException,
HttpHeaders httpHeaders,
HttpStatus httpStatus,
WebRequest webRequest
) {
//Fehlerliste im Antworttext gespeichert
List<ApiError> apiErrorList = new ArrayList<>();
List<ObjectError> objectErrorList = bindException.getAllErrors();
for (ObjectError objectError : objectErrorList) {
//Nachricht vom Fehlercode abrufen
String message = messageSource.getMessage(objectError, webRequest.getLocale());
//Erstellen Sie ein Fehlerobjekt für den Antworttext und speichern Sie es in der Liste
ApiError apiError = new ApiError();
apiError.setMessage(message);
apiErrorList.add(apiError);
}
return new ResponseEntity<>(apiErrorList, httpHeaders, httpStatus);
}
}
Wenn ein Validierungsfehler auftritt, löst der Controller eine "BindException" aus, in der die Fehlerinformationen gespeichert werden. Implementieren Sie in der Klasse mit "@ ControllerAdvice" den Prozess, den Sie auf jeden Controller anwenden möchten. Durch Erben von "ResponseEntityExceptionHandler" und Überschreiben der "handleBindException" -Methode können Sie die Antwort zum Zeitpunkt des Validierungsfehlers frei anpassen.
Hier wird es wie folgt angepasst.
objectError
in eine Fehlermeldung.Der Fehlercode wird in objectError
im folgenden Format gespeichert.
Einzeltermvalidierung: "Annotationsname + Klassenname (Kamelfall) + Feldname" Korrelationsvalidierung: "Fehlercode in Korrelationsvalidierung + Klassenname (Kamelfall) festgelegt"
Wenn Sie messages.properties
wie folgt vorbereiten, wird es in eine Nachricht konvertiert.
messages.properties
NotBlank.getUsersQuery.name=Die Eingabe eines Namens ist obligatorisch.
NotNull.getUsersQuery.lowerLimitAge=Die Eingabe des Mindestalters ist obligatorisch.
NotNull.getUsersQuery.upperLimitAge=Die Eingabe des Höchstalters ist obligatorisch.
reverseLimitAge.getUsersQuery=Geben Sie einen Wert an, der größer als das untere Grenzalter für das obere Grenzalter ist.
Recommended Posts