2

I am currently setting up a Spring MVC application (version 4.1.4.RELEASE) and I want the application to return a JSON string on a 404 error rather than the default html response. I am using Tomcat 8 as my server. I have what I think should be correct, however it isn't behaving in the manner that I expect. What I'm trying to do is based off of this answer.

public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{

    ...

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration){
        registration.setInitParameter("throwExceptionIfNoHandlerFound","true");
    }
}

and then I have an exception controller (which is different than the question I based my solution off of, however I don't believe that is an issue as I am under the impression that @ControllerAdvice is an acceptable way to manage this based off of the Spring Docs. It looks something like:

@ControllerAdvice
public class GlobalExceptionController{
    @ResponseStatus(value=HttpStatus.NOT_FOUND)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Message handleMethodNotSupported(HttpServletRequest request){
        ...
    }

    @ResponseStatus(value=HttpStatus.NOT_FOUND)
    @ExceptionHandler(NoSuchRequestHandlingMethodException.class)
    public Message handleBadRequest(HttpServletRequest request){
        ...
    }

    @ResponseStatus(value=HttpStatus.NOT_FOUND)
    @ExceptionHandler(NoHandlerFoundException.class)
    public Message requestHandlingNoHandlerFound(HttpServletRequest request){
        ...
    }

    ...

}

It continues to send back the default response. I know for a fact that it is hitting my customizeRegistration() function because breakpoints stop it, however, any breakpoints that I have in my GlobalException class are not hit. Also, the GlobalException class is within a package that is hit by a @ComponentScan() annotation, so I am fairly confident that it is also being handled by spring.

I assume I'm missing something obvious, any help would be greatly appreciated.

Community
  • 1
  • 1
S. Buda
  • 727
  • 7
  • 27

1 Answers1

1

I don't think the return type you're trying to use is supported. Have you tried changing your return value to ResponseEntity or adding a @ResponseBody annotation? From the docs:

  • A ModelAndView object (Servlet MVC or Portlet MVC).
  • A Model object, with the view name implicitly determined through a RequestToViewNameTranslator.
  • A Map object for exposing a model, with the view name implicitly determined through a RequestToViewNameTranslator.
  • A View object.
  • A String value which is interpreted as view name.
  • @ResponseBody annotated methods (Servlet-only) to set the response content. The return value will be converted to the response stream using message converters.
  • An HttpEntity or ResponseEntity object (Servlet-only) to set response headers and content. The ResponseEntity body will be converted and written to the response stream using message converters.
  • void if the method handles the response itself (by writing the response content directly, declaring an argument of type ServletResponse / HttpServletResponse / RenderResponse for that purpose) or if the view name is supposed to be implicitly determined through a RequestToViewNameTranslator (not declaring a response argument in the handler method signature; only applicable in a Servlet environment).
John R
  • 2,066
  • 1
  • 11
  • 17
  • Shouldn't that mean that it would throw an error when it tries to return something, rather than never explicitly hitting the functions? – S. Buda Feb 26 '15 at 19:29
  • I tried changing the response type to String that maps to a static html page in my project and got the same results. I suspect that- while that may be an issue, it isn't the cause of the behavior I'm seeing. – S. Buda Feb 26 '15 at 19:33
  • One other thing I noticed about the code is that all of those exceptions are Spring specific. It's possible that your exception handler isn't being called at all because those exceptions aren't thrown from within a method that's handling a web request, they're thrown before Spring even picks a method. Have you tried implementing [HandlerExceptionResolver](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/portlet/HandlerExceptionResolver.html)? – John R Feb 26 '15 at 19:42