title: Spring MVC REST Handing Bad Url (404) by returning JSON
body: <p>I am developing a REST service using SpringMVC, where I have @RequestMapping at class and method level. </p>
  
  <p>This application is currently configured to return error-page jsp configured in web.xml. </p>
  
  <pre><code>&lt;error-page&gt;
      &lt;error-code&gt;404&lt;/error-code&gt;
      &lt;location&gt;/resourceNotFound&lt;/location&gt;
  &lt;/error-page&gt;
  </code></pre>
  
  <p>I however want to return custom JSON instead of this error page.</p>
  
  <p>I am able to handle exception and return json for other exceptions, by writing this in controller, but not sure how and where to write the logic to return JSON when the url does not exist at all. </p>
  
  <pre><code>    @ExceptionHandler(TypeMismatchException.class)
          @ResponseStatus(value=HttpStatus.NOT_FOUND)
          @ResponseBody
          public ResponseEntity&lt;String&gt; handleTypeMismatchException(HttpServletRequest req, TypeMismatchException ex) {
  
              HttpHeaders headers = new HttpHeaders();
              headers.add("Content-Type", "application/json; charset=utf-8");
              Locale locale = LocaleContextHolder.getLocale();
              String errorMessage = messageSource.getMessage("error.patient.bad.request", null, locale);
  
              errorMessage += ex.getValue();
              String errorURL = req.getRequestURL().toString();
  
              ErrorInfo errorInfo = new ErrorInfo(errorURL, errorMessage);
              return new ResponseEntity&lt;String&gt;(errorInfo.toJson(), headers, HttpStatus.BAD_REQUEST);
  
          }
  </code></pre>
  
  <p><strong>I tried @ControllerAdvice, it works for other exception scenarios, but not when mapping is not avaialble,</strong></p>
  
  <pre><code>@ControllerAdvice
  public class RestExceptionProcessor {
  
      @Autowired
      private MessageSource messageSource;
  
      @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
      @ResponseStatus(value=HttpStatus.NOT_FOUND)
      @ResponseBody
      public ResponseEntity&lt;String&gt; requestMethodNotSupported(HttpServletRequest req, HttpRequestMethodNotSupportedException ex) {
          Locale locale = LocaleContextHolder.getLocale();
          String errorMessage = messageSource.getMessage("error.patient.bad.id", null, locale);
  
          String errorURL = req.getRequestURL().toString();
  
          ErrorInfo errorInfo = new ErrorInfo(errorURL, errorMessage);
          return new ResponseEntity&lt;String&gt;(errorInfo.toJson(), HttpStatus.BAD_REQUEST);
      }
  
      @ExceptionHandler(NoSuchRequestHandlingMethodException.class)
      @ResponseStatus(value=HttpStatus.NOT_FOUND)
      @ResponseBody
      public ResponseEntity&lt;String&gt; requestHandlingMethodNotSupported(HttpServletRequest req, NoSuchRequestHandlingMethodException ex) {
          Locale locale = LocaleContextHolder.getLocale();
          String errorMessage = messageSource.getMessage("error.patient.bad.id", null, locale);
  
          String errorURL = req.getRequestURL().toString();
  
          ErrorInfo errorInfo = new ErrorInfo(errorURL, errorMessage);
          return new ResponseEntity&lt;String&gt;(errorInfo.toJson(), HttpStatus.BAD_REQUEST);
      }
  
  
  }
  </code></pre>