Bean creation errors for request-scoped beans

metacubed :

When a Spring bean is annotated with SCOPE_REQUEST, it is created and destroyed every time a HTTP request is received by the servlet. If this bean creation fails, a server error is sent back to the caller.

In this trivial example, the creation of the MyInputs bean is dependent on the contents of the HTTP request.

@Configuration
class ApplicationConfiguration {

    @Bean
    @Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public MyInputs myInputs(HttpServletRequest request) {

        String header1 = request.getHeader("header1");
        if (header1 == null) {
            throw new MyException("header1 is missing");
        }
        return new MyInputs(header1);
    }
}

If the HTTP request does not contain a required header, a BeanCreationException will be thrown. This is translated into an unhelpful "500 Internal Server Error" response.

I would like to return a more user-friendly response code and body, for example, a "400 Bad Request" with a helpful message. How do I customize this response translation? I cannot find any lifecycle hooks which will allow this.


Note: This is how the request-scoped bean is consumed:

@RestController
public class MyController {

    private final Provider<MyInputs> myInputsProvider;

    @Autowired
    public MyController(Provider<MyInputs> myInputsProvider) {

        this.myInputsProvider = myInputsProvider;
    }

    @GetMapping("/do-stuff")
    public void doStuff() {

        // Get the inputs for the current request
        MyInputs myInputs = myInputsProvider.get();

        // ...
    }
}
Jonathan JOhx :

You can use @ControllerAdvice annotation in order to handle exceptions after are thrown.

Also you need to use @ExceptionHandler in order to handle the exception.

@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MyException.class)
    public final ResponseEntity<CustomError> handleException(MyException ex, WebRequest request) {
        CustomError error = new CustomError();            
        error.setMessage(ex.getMessage());
        error.setStatus(HttpStatus.BAD_REQUEST);
        return new ResponseEntity<>(error, null, HttpStatus.BAD_REQUEST);
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=125547&siteId=1
Recommended