Si vous préparez une classe de gestionnaire avec @ControllerAdvice , Le traitement des erreurs de validation de chaque contrôleur peut être traité à la fois.
Java 11
SpringBoot 2.3.3
Ce qui suit est une explication du contrôleur REST qui acquiert une liste d'utilisateurs en spécifiant des paramètres de recherche. Une validation d'entrée de la demande est fournie, et lorsqu'une erreur de validation est détectée, une erreur 400 est renvoyée avec un corps de réponse prédéterminé.
Ajoutez @ Validated
à l'argument pour que la validation soit effectuée.
La manipulation au moment de l'erreur n'est pas particulièrement effectuée ici.
@RestController
@RequiredArgsConstructor
public class UserController {
@NonNull
private final UserService userService;
@NonNull
private final GetUsersQueryValidator getUsersQueryValidator;
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.addValidators(getUsersQueryValidator);
}
/**
*Obtenir des informations sur l'utilisateur en spécifiant les conditions de recherche
*
* @param getUsersQuery Critères de recherche Paramètres de requête
* @retour Informations sur l'utilisateur recherché
*/
@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));
}
}
La classe à laquelle les paramètres de requête de la demande sont liés. «@ NotBlank» et «@ NotNull» sont ajoutés à chaque champ afin que la validation à un seul terme soit effectuée.
/**
*Paramètres de requête qui spécifient les conditions de recherche des utilisateurs
*/
@Data
public class GetUsersQuery {
/**
*Nom d'utilisateur
*/
@NotBlank
private String name;
/**
*Âge minimum
*/
@NotNull
private Integer lowerLimitAge;
/**
*Age maximum
*/
@NotNull
private Integer upperLimitAge;
}
Une erreur se produit lorsque l'âge limite inférieur du paramètre de requête dépasse l'âge limite supérieur.
/**
* {@link GetUsersQuery}Corrélation Varidata
*/
@Component
public class GetUsersQueryValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return GetUsersQuery.class.isAssignableFrom(clazz);
}
/**
*Mise en œuvre de la validation
*
* @Param target Cible de validation
* @erreurs de paramètres Erreurs détectées
*/
@Override
public void validate(Object target, Errors errors) {
//La validation de la corrélation n'est pas effectuée si une erreur de terme unique se produit dans l'âge limite supérieur ou inférieur.
if (errors.hasFieldErrors("lowerLimitAge") || errors.hasFieldErrors("upperLimitAge")) {
return;
}
GetUsersQuery getUsersQuery = GetUsersQuery.class.cast(target);
int lowerLimitAge = getUsersQuery.getLowerLimitAge();
int upperLimitAge = getUsersQuery.getUpperLimitAge();
//Si l'âge limite supérieur ne dépasse pas l'âge limite inférieur, une erreur se produira.
if (lowerLimitAge >= upperLimitAge) {
errors.reject("reverseLimitAge");
}
}
}
Lorsqu'une erreur se produit, un objet de ce type est stocké dans le corps de la réponse.
/**
*Informations d'erreur à définir dans le corps de la requête
*/
@Data
public class ApiError implements Serializable {
private static final long serialVersionUID = 1L;
private String message;
}
Préparez une classe de gestionnaire d'exceptions avec @ ControllerAdvice
comme indiqué ci-dessous.
/**
*Gestionnaire pour les exceptions levées sur le contrôleur
*/
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@Autowired
MessageSource messageSource;
/**
* {@link BindException}Manipulation
*
* @param bindException {@link BindException}
* @param httpHeaders {@link HttpHeaders}
* @param httpStatus {@link HttpStatus}
* @param webRequest {@link WebRequest}
* @retourner la réponse au client
*/
@Override
protected ResponseEntity<Object> handleBindException(
BindException bindException,
HttpHeaders httpHeaders,
HttpStatus httpStatus,
WebRequest webRequest
) {
//Liste d'erreurs stockée dans le corps de la réponse
List<ApiError> apiErrorList = new ArrayList<>();
List<ObjectError> objectErrorList = bindException.getAllErrors();
for (ObjectError objectError : objectErrorList) {
//Obtenir le message du code d'erreur
String message = messageSource.getMessage(objectError, webRequest.getLocale());
//Créez un objet d'erreur pour le corps de la réponse et stockez-le dans la liste
ApiError apiError = new ApiError();
apiError.setMessage(message);
apiErrorList.add(apiError);
}
return new ResponseEntity<>(apiErrorList, httpHeaders, httpStatus);
}
}
Lorsqu'une erreur de validation se produit, le contrôleur lance une BindException
qui stocke les informations d'erreur.
Dans la classe avec @ ControllerAdvice
, implémentez le processus que vous souhaitez appliquer à chaque contrôleur. En héritant de ResponseEntityExceptionHandler
et en remplaçant la méthode handleBindException
, vous pouvez librement personnaliser la réponse au moment de l'erreur de validation.
Ici, il est personnalisé comme suit.
--Spécifiez le corps de la réponse comme type ʻApiError. --Converti du code d'erreur de ʻobjectError
en message d'erreur.
Le code d'erreur est stocké dans ʻobjectError` au format suivant.
Validation d'un seul terme: "Nom d'annotation + nom de classe (cas camel) + nom de champ" Validation de la corrélation: "Code d'erreur défini dans la validation de la corrélation + nom de la classe (cas de chameau)"
Si vous préparez messages.properties
comme suit, il sera converti en message.
messages.properties
NotBlank.getUsersQuery.name=La saisie d'un nom est obligatoire.
NotNull.getUsersQuery.lowerLimitAge=La saisie de l'âge minimum est obligatoire.
NotNull.getUsersQuery.upperLimitAge=La saisie de l'âge maximum est obligatoire.
reverseLimitAge.getUsersQuery=Spécifiez une valeur supérieure à l'âge limite inférieur pour l'âge limite supérieur.
Recommended Posts