首页 > 解决方案 > 为无效的 UUID 提供 HttpStatus.BAD_REQUEST

问题描述

我提供了一个控制器方法:

@ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "get All Quotes By account id", content = {
                    @Content(mediaType = "application/json", array = @ArraySchema(schema = @Schema(implementation = Quote.class)))}),
            @ApiResponse(responseCode = "400", description = MessageConstant.EMPTY_REQUEST_BODY_MSG, content = @Content),
            @ApiResponse(responseCode = "404", description = MessageConstant.RESOURCE_NOT_FOUND_MSG, content = @Content),
            @ApiResponse(responseCode = "500", description = MessageConstant.INTERNAL_SERVER_ERROR_MSG, content = @Content)})

    @GetMapping("/accounts/{accountId}/quotes")
    public ResponseEntity<Object> getAllQuotesByAccountId(@PathVariable UUID accountId) {
        try {
            if (isInvalidUUID(accountId)) {
                return new ResponseEntity<>(ApiResponseMessage.getGenericApiResponse(Boolean.FALSE, HttpStatus.BAD_REQUEST,
                    MessageConstant.EMPTY_REQUEST_BODY_MSG), new HttpHeaders(), HttpStatus.BAD_REQUEST);
            }
            List<Quote> quotes = quoteService.getAllQuotesByAccount(accountId);
            if (quotes == null || quotes.isEmpty()) {
                return new ResponseEntity<>(ApiResponseMessage.getGenericApiResponse(Boolean.FALSE, HttpStatus.NOT_FOUND,
                        MessageConstant.RESOURCE_NOT_FOUND_MSG), new HttpHeaders(), HttpStatus.NOT_FOUND);
            }
            return new ResponseEntity<>(quotes, new HttpHeaders(), HttpStatus.OK);

        } catch (Exception ex) {
            log.error(MessageConstant.INTERNAL_SERVER_ERROR_MSG + ex.getMessage());
            return new ResponseEntity<>(ApiResponseMessage.getInternalServerError(), new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

这是我用于 UUID 检查的方法:

private boolean isInvalidUUID(UUID uuid) {
    return uuid == null || StringUtils.isBlank(uuid.toString());
}

现在,我想使用注释进行 UUID 验证:

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Constraint(validatedBy = {})
@Retention(RUNTIME)
@Pattern(regexp = "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$", flags = {Pattern.Flag.CASE_INSENSITIVE})
public @interface UUIDValidated {
    
    String message() default "UUID format is invalid";

    Class<?>[] groups() default {};
    
    Class<? extends Payload>[] payload() default {};
}

所以我想使用注释的方法是这样的:

public ResponseEntity<Object> getAllQuotesByAccountId(@PathVariable @UUIDValidator UUID accountId){

   .....
}

当 UUID 无效时如何模拟 HttpStatus.BAD_REQUEST 以及使用此注释时 UUID 无效时我们得到的错误是什么?

标签: javaspring

解决方案


当使用此注释的 UUID 无效时我们得到什么错误

是您可以验证自己的东西(我的钱在 a 上),您可以通过简单地向控制器添加异常处理程序方法来MethodArgumentNotValidException模拟:HttpStatus.BAD_REQUEST

@RestController
@Validated
public class QuoteController {

    @GetMapping("/accounts/{accountId}/quotes")
    public ResponseEntity<Object> getAllQuotesByAccountId(@PathVariable @UUIDValidator UUID accountId) {
    ...// your code
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    String handleMethodArgumentNotValid(MethodArgumentNotValidException e) {
        return "Validation failed: " + e.getMessage(); //or: build custom error message using getAllErrors(), or: return an error object instead of a String, or: return ResponseEntity to further customize the response
    }
}

作为旁注,如果处理验证错误的方式应该在您的应用程序中的所有控制器之间保持一致(而不仅仅是为这个特定的控制器定义),请考虑将处理程序方法移动到@ControllerAdvice.


推荐阅读