spring - SpringBoot 处理 @RequestParam 异常
问题描述
我有控制器和方法 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);
}
父类:
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 {};
}
验证器类
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>
推荐阅读
- r - 如何在 powerbi 中使用 dygraphs?
- css - 自定义范围按钮不显示图标
- c - 当输入是二进制数时,如何反转二进制数并打印它们?
- c++ - 按行格式化日志表
- python - 如何将类参数名称赋予函数以更改此参数
- c - 用星号绘制三角形 int 的问题
- laravel - Vuejs中挂载不同父组件时如何确保子组件不总是重新加载
- python - 使用流水线 hgetall 进行 Redis 慢速查询
- java - aws - java8 - 无法从 START_OBJECT 令牌中反序列化 java.lang.String 的实例
- reactjs - React - 完成表单提交后重定向