@ControllerAdvice Spring - 返回类型作为自定义对象而不是ModelAndView

时间:2014-05-21 15:41:48

标签: java spring rest exception-handling

我的任务是将控制器中的@RequestMapping方法抛出的异常暴露为UI作为JSON对象。在谷歌搜索时,我发现了有关ControllerAdvice的信息,我想我需要类似的东西。我在所有示例中看到的唯一问题是返回类型 - 它们返回ModelAndView而我需要返回一个自定义对象作为返回类型。这是我的示例代码:

控制器类:

@RequestMapping(value="/abc", method=RequestMethod.GET)
@ResponseBody
public MyModel getResponse(@RequestParam String id, 
                            HttpServletRequest request) throws SQLException 
   {
    boolean exceptionFlag = true;  
         if (exceptionFlag){  
        throw new SQLException();  
    } 
     return myModel;
  }

ExceptionHandlerClass:

@ControllerAdvice
public class ExceptionHandler {
        @ExceptionHandler(SQLException.class)  
        public MyCustomException handleSQLException(SQLException exception)
        {
            MyCustomException ex = new MyCustomException();
            ex.setExceptionCode("MyCode");
            ex.setExceptionDescription(exception.getMessage());     
            return ex;
        }

它抱怨它无法找到JSP(WARN:org.apache.jasper.servlet.JspServlet:PWC6117:File" rest \ support \ abc.jsp" not foundnull)

4 个答案:

答案 0 :(得分:1)

ExceptionHandler好赶上SQLException? 如果是这样,也许这会做的伎俩:

@ControllerAdvice
public class ExceptionHandler {

    @ResponseBody
    @ExceptionHandler(SQLException.class)  
    public MyCustomException handleSQLException(SQLException exception) {
        MyCustomException ex = new MyCustomException();
        ex.setExceptionCode("MyCode");
        ex.setExceptionDescription(exception.getMessage());     
        return ex;
    }

}

答案 1 :(得分:1)

您可能希望将异常包装在ResponseEntity<T>内,这样您也可以返回一个HttpStatus代码和json主体。

@ControllerAdvice
@RequestMapping(produces = "application/json")
@ResponseBody
public class RestControllerAdvice {


    @ExceptionHandler(EntityNotFoundException .class)
    public ResponseEntity<Map<String,Object>> notFoundException(final EntityNotFoundException e) {

        Map<String,Object> errorInfo = new HashMap<>();
        errorInfo.put("error message",e.getMessage());
        errorInfo.put("timestamp", new Date());
        return new ResponseEntity<Map<String,Object>>(errorInfo, HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(QueryParameterNotSupportedException.class)
    public ResponseEntity<Map<String,Object>> unrecognizedParameter(final QueryParameterNotSupportedException e) {

        Map<String,Object> errorInfo = new LinkedHashMap<>();
        errorInfo.put("timestamp", new Date());
        errorInfo.put("errorMessage",e.getMessage());
        errorInfo.put("allowableParameters",e.getValidArgs());

        return new ResponseEntity<Map<String,Object>>(errorInfo, HttpStatus.BAD_REQUEST);

    }

在上面的示例中,类型“T”是Map<String,Object>,但它可以是Jackson可序列化的任何类型。另外,请注意存在一个类级别@ResponseBody注释,它指示spring在返回之前将类中每个方法的返回方法转换为json。

答案 2 :(得分:0)

如果在控制器操作方法上使用@ResponseBody注释,则可以返回任何类型。你的课程路径上需要Jackson2。

答案 3 :(得分:0)

你必须像@Basemasta那样修改异常处理程序方法:

@ControllerAdvice
public class ExceptionHandler {

    @ResponseBody
    @ExceptionHandler(SQLException.class)  
    public MyCustomException handleSQLException(SQLException exception) {
        MyCustomException ex = new MyCustomException();
        ex.setExceptionCode("MyCode");
        ex.setExceptionDescription(exception.getMessage());     
        return ex;
    }
}

在你的应用程序中包含Jackson mapper-Context.xml ...这个配置对我有用:

<bean id="jacksonMessageChanger" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">         <property name="supportedMediaTypes" value="application/json"/>
 </bean>
 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
 <property name="messageConverters">
     <util:list id="beanList">
     <ref bean="jacksonMessageChanger"/>
     </util:list>
 </property>
</bean>

这里有一个从Spring返回JSON的教程:http://www.journaldev.com/2552/spring-restful-web-service-example-with-json-jackson-and-client-program