Returning JSON with spring on 404 in XML free proj

2020-04-29 16:36发布

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.

1条回答
姐就是有狂的资本
2楼-- · 2020-04-29 16:52

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).
查看更多
登录 后发表回答