【问题标题】:@ControllerAdvice Spring - Return type as a custom object and not ModelAndView@ControllerAdvice Spring - 作为自定义对象返回类型而不是 ModelAndView
【发布时间】:2014-05-21 15:41:48
【问题描述】:

我的任务是将控制器中 @RequestMapping 方法抛出的异常作为 JSON 对象公开给 UI。在谷歌搜索时,我发现了 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;
  }

异常处理程序类:

@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)

【问题讨论】:

    标签: java spring rest exception-handling


    【解决方案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&lt;String,Object&gt;,但它可以是 Jackson 可序列化的任何类型。另外,请注意存在一个类级别的@ResponseBody 注解,它指示spring 在返回之前将类中每个方法的返回方法转换为json。

    【讨论】:

      【解决方案2】:

      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;
          }
      
      }
      

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • 非常感谢您的回复,尼尔。我已经用代码和我得到的错误更新了我的问题。你能帮忙吗?
        【解决方案4】:

        您必须像@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;
            }
        }
        

        并在您的 application-Context.xml 中包含 Jackson 映射器...此配置对我有用:

        <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

        【讨论】:

          猜你喜欢
          • 2020-02-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-06
          • 1970-01-01
          • 1970-01-01
          • 2022-06-17
          相关资源
          最近更新 更多