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>
我有控制器,方法 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>