英文:
getting ConstraintViolationException instead of MethodArgumentNotValidException when using @valid with @RequestBody in the controller
问题
我正在继续学习Spring Boot的旅程,目前我在两种相似的异常之间陷入困境,无论我在控制器/服务级别与@RequestBody一起使用@valid或@validate,都应该获得MethodArgumentNotValidException,而在进行Post和Update API调用时我得到了ConstraintViolationException。一再调用全局异常处理程序ExceptionHAndler类的方法,显示ConstraintViolationException。
PostController.java
@RestController
@RequestMapping("/api/posts")
public class PostController {
@Autowired
private PostService postService;
@PostMapping
public ResponseEntity<PostDTO> createPost(@Valid @RequestBody PostDTO postDTO){
return new ResponseEntity<>(postService.createPost(postDTO),HttpStatus.CREATED);
}
@PostMapping(path = "/multiple")
public ResponseEntity<List<PostDTO>> createMultiplePosts(@Valid @RequestBody List<PostDTO> postDTO){
return new ResponseEntity<>(postService.createMultiplePosts(postDTO),HttpStatus.CREATED);
}
}
Entity Class: Posts.java
@Entity
@Table(name = "posts", uniqueConstraints = {@UniqueConstraint(columnNames = {"titles"})})
public class Posts {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name = "titles")
@NotEmpty
@Size(min = 2,message = "post title should contain atleast 2 character")
private String title;
@Column(name = "description")
@NotEmpty
@Size(min = 10,message = "post description should contain atleast 2 character")
private String description;
@Column(name = "content")
@NotEmpty
private String content;
}
GlobalException.java
@ControllerAdvice
public class GlobalException extends ResponseEntityExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalException.class);
@ExceptionHandler(ResouceNotFoundException.class)
ResponseEntity<ErrorDetails> PostNotFoundExceptionHandler(ResouceNotFoundException exception, WebRequest webRequest){
// ... (unchanged)
}
@ExceptionHandler(BlogApiException.class)
ResponseEntity<ErrorDetails> CommentNotFoundExceptionHandler(BlogApiException exception, WebRequest webRequest){
// ... (unchanged)
}
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request){
// ... (unchanged)
}
@ExceptionHandler(Exception.class)
ResponseEntity<ErrorDetails> GlobalExceptionHandler(Exception exception, WebRequest webRequest){
// ... (unchanged)
}
}
我尝试修改RequestBody JSON,在类级别和方法级别在@RequestBody注解之后尝试@validated注解,仍然得到相同的异常。请帮助我理解为什么我会得到这个异常,尝试与Spring Boot Starter Validation依赖项的版本进行调整,目前使用的是3.0.4版本的starter-validation依赖项,Java版本是17.0.7。
英文:
i am continuing my journey to learn Spring boot, right now i am stuck between two similar kind of exceptions, wherever i found i have got the answer that if @valid or @validate used at controller/service level along with @RequestBody we should get MethodArgumentNotValidException
whereas, i am getting ConstraintViolationException during post and update API calls. again and again the call is going in globalExceptionHandler method of ExceptionHAndler class, where it is showing constraintviolationexception.
PostController.java
@RestController
@RequestMapping("/api/posts")
public class PostController {
@Autowired
private PostService postService;
//rest API endpoint to post http:localhost:8080/api/posts
@PostMapping
public ResponseEntity<PostDTO> createPost(@Valid @RequestBody PostDTO postDTO){
return new ResponseEntity<>(postService.createPost(postDTO),HttpStatus.CREATED);
}
@PostMapping(path = "/multiple")
public ResponseEntity<List<PostDTO>> createMultiplePosts(@Valid @RequestBody List<PostDTO> postDTO){
return new ResponseEntity<>(postService.createMultiplePosts(postDTO),HttpStatus.CREATED);
}
Entity Class:
Posts.java
@Entity
@Table(name = "posts", uniqueConstraints = {@UniqueConstraint(columnNames = {"titles"})})
public class Posts {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name = "titles")
@NotEmpty
@Size(min = 2,message = "post title should contain atleast 2 character")
private String title;
@Column(name = "description")
@NotEmpty
@Size(min = 10,message = "post description should contain atleast 2 character")
private String description;
@Column(name = "content")
@NotEmpty
private String content;
GlobalException.java
@ControllerAdvice
public class GlobalException extends ResponseEntityExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalException.class);
@ExceptionHandler(ResouceNotFoundException.class)
ResponseEntity<ErrorDetails> PostNotFoundExceptionHandler(ResouceNotFoundException exception, WebRequest webRequest){
ErrorDetails errorDetails =new ErrorDetails(new Date(),exception.getMessage(),webRequest.getDescription(false));
return new ResponseEntity<>(errorDetails,HttpStatus.NOT_FOUND);
}
@ExceptionHandler(BlogApiException.class)
ResponseEntity<ErrorDetails> CommentNotFoundExceptionHandler(BlogApiException exception, WebRequest webRequest){
ErrorDetails errorDetails =new ErrorDetails(new Date(),exception.getMessage(),webRequest.getDescription(false));
return new ResponseEntity<>(errorDetails,HttpStatus.NOT_FOUND);
}
@Override
// @ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request){
logger.info("inside handleMethodArgumentNotValid class");
Map<String, String> errorsMap =new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error)->{
String fieldNameString = ((FieldError)error).getField();
String messageString = error.getDefaultMessage();
errorsMap.put(fieldNameString, messageString);
});
return new ResponseEntity<>(errorsMap,HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Exception.class)
ResponseEntity<ErrorDetails> GlobalExceptionHandler(Exception exception, WebRequest webRequest){
logger.info("inside GlobalExceptionHandler class");
ErrorDetails errorDetails =new ErrorDetails(new Date(),exception.getMessage(),webRequest.getDescription(false));
return new ResponseEntity<>(errorDetails,HttpStatus.BAD_REQUEST);
}
}
i tried modifying RequestBody JSON, tried @validated annotation at class level, and at method level after @RequestBody annotation as well, still getting same exception.
please help me to understand why am I getting this exception, tried playing with versions of spring boot starter validation dependency.
currently using 3.0.4 version of starter-validation dependency
Java version is 17.0.7
答案1
得分: 0
为什么你认为应该获得 MethodArgumentNotValidException
?当请求体违反了一些约束时,似乎期望 ConstraintViolationException
是完全合理的异常。我在这里看不到问题。只需将你的 ExceptionHandler
更改为捕获 ConstraintViolationException
并按照你的需求处理它。
英文:
Why do you think you should get MethodArgumentNotValidException
? ConstraintViolationException
seems to be totally reasonable exception to expect, when some constraints were violated by your request body. I don't see a problem here. Just change your ExceptionHandler
to catch ConstraintViolationException
and do whatever you want with it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论