Spring boot 3.0.0+ @Override error in ResponseEntityExceptionHandler
Asked Answered
C

4

12

I am following this example (Validate Request Body and Parameter in Spring Boot in medium) and this example to implement a Handler to handle the correctness of a JSON as a parameter. The concepts are somewhat clear but having reached this point the use of @Override for the handleMethodArgumentNotValid method gives me an error like: Method does not override method from its superclass.

I have searched online to figure out how to solve this problem but I am probably missing something.

package com.tericcabrel.hotel.exceptions;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
  @Override
  protected ResponseEntity<Object> handleMethodArgumentNotValid(
      MethodArgumentNotValidException ex, HttpHeaders headers,
      HttpStatus status, WebRequest request) {

    Map<String, List<String>> body = new HashMap<>();

    List<String> errors = ex.getBindingResult()
        .getFieldErrors()
        .stream()
        .map(DefaultMessageSourceResolvable::getDefaultMessage)
        .collect(Collectors.toList());

    body.put("errors", errors);

    return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
  }
}
Concupiscence answered 9/3, 2023 at 21:30 Comment(0)
C
42

I report the solution if possibly other people follow the tutorial. In the official documentation the method (ResponseEntityExceptionHandler) reports the class HttpStatusCode and not HttpStatus

Concupiscence answered 9/3, 2023 at 21:38 Comment(4)
Nice findings. Helped me a lot.Unsteady
Wow. Thanks. There is a lot of small things when you pass from Spring Boot 2.7.x to Spring Boot 3.x. This is one of themArchuleta
@Gianni it would be nice to mark this as an accepted answerPewee
Very well, thanks. Works fine to me.Lunn
S
5

I had a similar problem today.

I've solved it NOT extending from ResponseEntityExceptionHandler, replacing the @Override annotation with @ExceptionHandler(MethodArgumentNotValidException.class), and removing the parameters headers and status from the method.

I didn't try your particular code. Maybe you have to modify it a little bit, but basically you should write something like this:

@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(MethodArgumentNotValidException.class)
    protected ResponseEntity<Object> handleMethodArgumentNotValid(
        MethodArgumentNotValidException ex, WebRequest request) {

        Map<String, List<String>> body = new HashMap<>();

        List<String> errors = ex.getBindingResult()
            .getFieldErrors()
            .stream()
            .map(DefaultMessageSourceResolvable::getDefaultMessage)
            .collect(Collectors.toList());

        body.put("errors", errors);

        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
    }
}
Swedenborgianism answered 10/5, 2023 at 1:26 Comment(0)
B
4

The accepted response seems pretty clear, however it was unclear to me in the beginning so the reason by which this error is appearing is because the method does not have this signature anymore:

  protected ResponseEntity<Object> handleMethodArgumentNotValid(
      MethodArgumentNotValidException ex, HttpHeaders headers,
      HttpStatus status, WebRequest request) 

but has this one:

  protected ResponseEntity<Object> handleMethodArgumentNotValid(
      MethodArgumentNotValidException ex, HttpHeaders headers,
      HttpStatusCode status, WebRequest request) 

Notice the data type for status argument that changed from HttpStatus to HttpStatusCode

So changing the data type is required and will solve the issue.

Bubbly answered 24/11, 2023 at 22:46 Comment(0)
R
0

According to this article : https://dzone.com/articles/upgrade-guide-to-spring-boot-3-for-spring-data-jpa-3-and-querydsl-5

In spring MVC 6, the method accepts HttpStatusCode and not HttpStatus as its argument. HttpStatus was there in spring MVC 5.

Alternatively you can: use the generic way of catching the error using the signature: (avoid using the override and also you can avoid extending the ResponseEntityExceptionHandler class)

@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, WebRequest request)

The reason why the alternative solution works: spring on validating the arguments in the controller methods, if exception occurs throws this error, and now just like handling other exceptions in the GlobalExceptionHandler class, you can handle this too. required exception is being thrown

Ruling answered 3/8 at 7:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.