Search code examples
springspring-mvcspring-bootspring-dataspring-boot-actuator

How to validated rest url in spring boot?


validate Rest URL in spring boot. Requirement: If I hit the wrong URL then it should throw a custom exception. ex. Correct URL is "/fulfillment/600747l/send_to_hub" If I hit "/api/600747l/send_to_hub_1" then it should return exception like "404:- URL not Found.".

Right now it returning "500 : -

 {
  "timestamp": 1531995246549,
  "status": 500,
  "error": "Internal Server Error",
  "message": "Invalid Request URL.",
  "path": "/api/600747l/send_to_hub_1"
}"

Solution

  • you need to write NewClass with annotation @ControllerAdvice which will redirect all exceptions to this NewClass. example

    Your Custom Exception Class:

    @Data
    @AllArgsConstructor
    @EqualsAndHashCode(callSuper = false)
    public class IOApiException extends IOException {
        private ErrorReason errorReason;
        public IOApiException(String message, ErrorReason errorReason) {
            super(message);
            this.errorReason = errorReason;
        }
    }
    

    Now the CustomExceptionHandler Class -

    @ControllerAdvice
    @RestController
    public class GlobalExceptionHandler {
        Logger logger = LoggerFactory.getLogger(this.getClass());
    
    
        @ResponseStatus(HttpStatus.UNAUTHORIZED)
        @ExceptionHandler(value = IOApiException.class)
        public GlobalErrorResponse handleException(IOApiException e) {
            logger.error("UNAUTHORIZED: ", e);
            return new GlobalErrorResponse("URL Not Found", HttpStatus.UNAUTHORIZED.value(), e.getErrorReason());
        }
    
    
     //this to handle customErrorResponseClasses
    public GlobalErrorResponse getErrorResponseFromGenericException(Exception ex) {
        if (ex == null) {
            return handleException(new Exception("INTERNAL_SERVER_ERROR"));
        } 
         else if (ex instanceof IOApiException) {
            return handleException((IOApiException) ex);
        }
    }
    

    Now Your error response class:

    public class GlobalErrorResponse {
        private String message;
        @JsonIgnore
        private int statusCode;
        private ErrorReason reason;
    }
    

    ErrorReason Class

    public enum ErrorReason {
        INTERNAL_SERVER_ERROR,
        INVALID_REQUEST_PARAMETER,
        INVALID_URL
    }
    

    add and register one filter who calls the GlobalExceptionHandler in exception case like this

      public class ExceptionHandlerFilter implements Filter {
        private final GlobalExceptionHandler globalExceptionHandler;
        public ExceptionHandlerFilter(GlobalExceptionHandler globalExceptionHandler) {
            this.globalExceptionHandler = globalExceptionHandler;
        }
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            try {
                chain.doFilter(request, response);
            } catch (Exception exception) {
                HttpServletResponse httpResponse = (HttpServletResponse) response;
                GlobalErrorResponse errorResponse = globalExceptionHandler.getErrorResponseFromGenericException(exception);
                httpResponse.setStatus(errorResponse.getStatusCode());
                response.getWriter().write(new ObjectMapper().writeValueAsString(errorResponse));
            }
        }
    
        @Override
        public void destroy() {
    
        }
    }
    

    Like this you can add as many exceptions you want.. and can handle it manually.