Spring Boot 处理@RequestParam 异常

SpringBoot handle @RequestParam exception

我有控制器,方法 deleteFolder 有 @RequestParam:

@RestController
    public class FolderController extends BaseController {

@DeleteMapping(path = Const.APIVersions.API_V1 + "/folders", params = "id")
public ResponseEntity<HttpStatus> deleteFolder(KeycloakAuthenticationToken authentication, @RequestParam Long id) throws EntityNotFoundException {
    folderService.deleteFolder(id, authentication.getName());
    return ResponseEntity.ok(HttpStatus.OK);
}

parent class:

public abstract class BaseController {
    @ExceptionHandler({MissingServletRequestParameterException.class,
            UnsatisfiedServletRequestParameterException.class, MethodArgumentTypeMismatchException.class,
            IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<ErrorResponse> handleMissingServletRequestParameter(MissingServletRequestParameterException exception) {
        return ResponseEntity
                .status(HttpStatus.BAD_REQUEST)
                .body(new ErrorResponse(HttpStatus.BAD_REQUEST.value(), exception.getMessage()));
    }

我想在缺少所需参数时处理异常。但是该异常处理程序不想捕获从 deletFolder 方法引发的异常。

任何其他处理程序都有效。

您必须创建自定义 ConstraintValidator 并捕获 ConstraintViolationException 以便您的基础控制器变为


import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;

import javax.validation.*;

public abstract class BaseController {


    @ExceptionHandler({ConstraintViolationException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<ErrorResponse> handlerFolderNotFoundException(ConstraintViolationException exception) {
        return ResponseEntity
                .status(HttpStatus.BAD_REQUEST)
                .body(new ErrorResponse(HttpStatus.BAD_REQUEST.value(), exception.getMessage()));
    }
}

验证注释


import javax.validation.*;
import java.lang.annotation.*;

@Constraint(validatedBy = FolderValidationConstraint.class)
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidateFolder {

    String message() default "Error validating folder name";

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

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

}

验证者class

import lombok.extern.slf4j.*;

import javax.validation.*;
import java.io.*;

@Slf4j
public class FolderValidationConstraint implements ConstraintValidator<ValidateFolder, String> {

    @Override
    public boolean isValid(String path, ConstraintValidatorContext constraintValidatorContext) {
        return new File("/home/ashish/Documents/test-delete/" + path).exists();
    }
}

控制器

import org.springframework.validation.annotation.*;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.util.*;

@Validated
@RestController
@RequestMapping(path = "/folders")
public class FolderController extends BaseController {

    @GetMapping
    public Map<String, Boolean> delete(@ValidateFolder @RequestParam("name") String folderName) {
        final File path = new File("/home/ashish/Documents/test-delete/" + folderName);
        return Map.of("exists", path.exists());
    }
}

请务必在pom.xml

中添加依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-validation</artifactId>
</dependency>