1

I have a controller advice that handle all validation exception thrown by my application as below.

@RestControllerAdvice
public class RestApiExceptionController {

    @ExceptionHandler(ValidationErrorException.class)
    public ResponseEntity<?> appNotFoundException(ValidationErrorException exception) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body(new ErrorResponse(exception.getErrorCode(), exception.getMessage())); 
    }
}

In my way, I would like to create a filter that will make validation to every request and throw custom exception when necessary. But the thing is that I cannot throw custom exception as show below.

public class ValidationFilter implements Filter {
    ...
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
        throws IOException, ServletException {
        throw new ValidationErrorException(); // This is impossible
    }
    ...
}

How can I throw the ValidationErrorException in this case or there are other better ways to handle such task.

Ponleu
  • 1,492
  • 12
  • 27
  • Yes you can... It just has to be either a `RuntimeException` or a `ServletException`. Also this has nothing to do with Spring but general Servlet API (or even general java programming). – M. Deinum Dec 06 '16 at 08:06

1 Answers1

3

The validations are generally done on the request objects which are in general available in Controller layer after they are transformed from request format to server processing format. e.g. JSON to Java object.

So the validation should be performed or triggered on Controller layer once the request is reached by completing your entire filter chaining.

Any validation exception thrown then later on can be handled in your following handler,

@RestControllerAdvice
public class RestApiExceptionController {

    @ExceptionHandler(ValidationErrorException.class)
    public ResponseEntity<?> appNotFoundException(ValidationErrorException exception) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body(new ErrorResponse(exception.getErrorCode(), exception.getMessage())); 
    }
}

The very much one of the purpose of filters is,

To intercept requests from a client before they access a resource at back end.

So filters in real don't have the actual resource yet to be validated. They are available once the control reaches to correct component and in your case it is Controller.

So better approach is not to do any resource based validations at filter components.

ScanQR
  • 3,740
  • 1
  • 13
  • 30
  • You are correct. But how about when I need user to attach encrypted secret code to HTTP Header and I would like the Filter to validate every request and throw ValidationErrorException if the secret is not valid? – Ponleu Dec 12 '16 at 04:49
  • @ChhornPonleu again this is more of design decisions. Please look for Spring Security module. You are here trying to do authorization / authentication on request. It has all such security related features available. Also So throw Security exceptions and not validation exceptions. – ScanQR Dec 12 '16 at 05:14
  • It seems like Spring Security has quite more functionalities than what I need. That is why I seek for such very simple solution. – Ponleu Dec 12 '16 at 06:24