如果在 spring boot 中路径参数不是 Long,如何抛出 NoHandlerFoundException
How to throw NoHandlerFoundException if path param is not Long in springboot
目前有如下GetMapping
@GetMapping(value = "/{id}")
public ResponseEntity<Dog> getTrainById(@PathVariable Long id) {
Dog dog= animalService.getAnimalById(id);
return new ResponseEntity<>(Dog , HttpStatus.OK);
}
现在如果有人访问 http://localhost:8080/api/animal/1,它 returns 动物。
但是如果有人在没有将 Long 变量作为路径参数的情况下访问此端点,我需要抛出 NoHandlerFoundException,这意味着像这样 http://localhost:8080/api/animal/asdsad
如果有人能告诉我实现此目标的方法,将不胜感激
我还有如下的全局异常处理
@ControllerAdvice
public class DemoExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<GenericResponse> customHandleNotFound(Exception ex, WebRequest request)
{
return new ResponseEntity<>(new GenericResponse(ex.getMessage(), null), HttpStatus.NOT_FOUND);
}
@Override
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
return new ResponseEntity<>(new GenericResponse("invalid endpoint", null), HttpStatus.METHOD_NOT_ALLOWED);
}
}
在这种情况下,请求无法解析为控制器方法的参数类型,它将抛出 MethodArgumentTypeMismatchException
.
所以解决问题最有效的方法就是想着如何直接处理MethodArgumentTypeMismatchException
而不是想着如何让它重新抛出NoHandlerFoundException
。所以你可以简单地创建一个 @ControllerAdvice
来处理 MethodArgumentTypeMismatchException
:
@ControllerAdvice
public class DemoExceptionHandler {
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<Object> handle(MethodArgumentTypeMismatchException ex) {
return new ResponseEntity<>( GenericResponse("invalid endpoint", null), HttpStatus.METHOD_NOT_ALLOWED);
}
}
它将应用于抛出此类异常的所有控制器。如果你只是想让它申请一个特定的控制器而不是全局的,你可以这样做:
@RestController
@RequestMapping("/foo")
public class FooController {
@GetMapping(value = "/{id}")
public ResponseEntity<Dog> getTrainById(@PathVariable Long id) {
}
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<Object> handleMethodArgumentTypeMismatchException() {
return new ResponseEntity<>( GenericResponse("invalid endpoint", null), HttpStatus.METHOD_NOT_ALLOWED);
}
}
目前有如下GetMapping
@GetMapping(value = "/{id}")
public ResponseEntity<Dog> getTrainById(@PathVariable Long id) {
Dog dog= animalService.getAnimalById(id);
return new ResponseEntity<>(Dog , HttpStatus.OK);
}
现在如果有人访问 http://localhost:8080/api/animal/1,它 returns 动物。
但是如果有人在没有将 Long 变量作为路径参数的情况下访问此端点,我需要抛出 NoHandlerFoundException,这意味着像这样 http://localhost:8080/api/animal/asdsad
如果有人能告诉我实现此目标的方法,将不胜感激
我还有如下的全局异常处理
@ControllerAdvice
public class DemoExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(EntityNotFoundException.class)
public ResponseEntity<GenericResponse> customHandleNotFound(Exception ex, WebRequest request)
{
return new ResponseEntity<>(new GenericResponse(ex.getMessage(), null), HttpStatus.NOT_FOUND);
}
@Override
protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
return new ResponseEntity<>(new GenericResponse("invalid endpoint", null), HttpStatus.METHOD_NOT_ALLOWED);
}
}
在这种情况下,请求无法解析为控制器方法的参数类型,它将抛出 MethodArgumentTypeMismatchException
.
所以解决问题最有效的方法就是想着如何直接处理MethodArgumentTypeMismatchException
而不是想着如何让它重新抛出NoHandlerFoundException
。所以你可以简单地创建一个 @ControllerAdvice
来处理 MethodArgumentTypeMismatchException
:
@ControllerAdvice
public class DemoExceptionHandler {
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<Object> handle(MethodArgumentTypeMismatchException ex) {
return new ResponseEntity<>( GenericResponse("invalid endpoint", null), HttpStatus.METHOD_NOT_ALLOWED);
}
}
它将应用于抛出此类异常的所有控制器。如果你只是想让它申请一个特定的控制器而不是全局的,你可以这样做:
@RestController
@RequestMapping("/foo")
public class FooController {
@GetMapping(value = "/{id}")
public ResponseEntity<Dog> getTrainById(@PathVariable Long id) {
}
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<Object> handleMethodArgumentTypeMismatchException() {
return new ResponseEntity<>( GenericResponse("invalid endpoint", null), HttpStatus.METHOD_NOT_ALLOWED);
}
}