2016-02-12 65 views
5

我使用Spring引導1.3.X和有以下幾點:春季啓動@ExceptionHandler隱藏例外名稱

@RestController 
@RequestMapping(path = "/foo") 
public class FooController { 

    @RequestMapping(method = RequestMethod.GET, params = { "fooBar" }) 
    public Collection<Entry> firstFoo() { 
     //Do something 
    } 

    @RequestMapping(method = RequestMethod.GET, params = { "anotherFooBar" }) 
    public Collection<Entry> secondFoo() { 
     //Do something other 
    } 

} 

預期其中一期工程。當傳遞一個錯誤的PARAM,以下異常引發:

{ 
    "error": "Bad Request", 
    "exception": "org.springframework.web.bind.UnsatisfiedServletRequestParameterException", 
    "message": "Parameter conditions \"fooBar\" OR \"anotherFooBar\" not met for actual request parameters: elementalFormulae={C11}", 
    "path": "/foo", 
    "status": 400, 
    "timestamp": 1455287433961 
} 

然後我創建了一個ExceptionHandler,如下圖所示:

@ControllerAdvice 
public class ExcptionController { 

    @ResponseStatus(value=HttpStatus.BAD_REQUEST, reason="Invalid parameter") 
    @ExceptionHandler(UnsatisfiedServletRequestParameterException.class) 
    private void foo() { 
     //Log exception 
    } 
} 

這就提出了以下異常:

{ 
    "error": "Bad Request", 
    "exception": "org.springframework.web.bind.UnsatisfiedServletRequestParameterException", 
    "message": "Invalid parameter", 
    "path": "/api/foo", 
    "status": 400, 
    "timestamp": 1455287904886 
} 

是它可能會從JSON表示中排除例外字段?

+0

@JSONIgnore會訣竅嗎? –

回答

7

您可以在您的控制器建議中獲得錯誤屬性,然後僅保留暴露字段。類似如下:

@ControllerAdvice 
public class ExcptionController { 
    private static final List<String> EXPOSABLE_FIELDS = asList("timestamp", "status", "error", "message", "path"); 

    @Autowired private ErrorAttributes errorAttributes; 

    @ExceptionHandler(UnsatisfiedServletRequestParameterException.class) 
    private ResponseEntity foo(HttpServletRequest request) { 
     Map<String, Object> errors = getErrorAttributes(request); 
     errors.put("message", "Invalid parameter"); 

     return ResponseEntity.badRequest().body(errors); 
    } 

    private Map<String, Object> getErrorAttributes(HttpServletRequest request) { 
     ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); 
     final boolean WITHOUT_STACK_TRACE = false; 
     Map<String, Object> attributes = errorAttributes.getErrorAttributes(requestAttributes, WITHOUT_STACK_TRACE); 

     // log exception before removing it 
     attributes.keySet().removeIf(key -> !EXPOSABLE_FIELDS.contains(key)); 

     return attributes; 
    } 
} 
+0

這種工作,即EXPOSABLE_FIELDS中未列出的字段,將從錯誤屬性中刪除,但返回的JSON仍然如上所示 – tplacht

+0

「exception」字段仍然存在? –

+0

是的,它仍然顯示,但錯誤不再包含該字段。 – tplacht

3

我已經解決了這個bean風格。將下面的bean定義添加到替代ErrorAttributes的REST層配置中,在我的情況下使用了已解決的問題,在異常處理中沒有任何運行時代碼。

@Bean 
public ErrorAttributes errorAttributes() { 
    return new DefaultErrorAttributes() { 

     @Override 
     public Map<String, Object> getErrorAttributes(
       RequestAttributes requestAttributes, 
       boolean includeStackTrace) { 

      Map<String, Object> errorAttributes 
       = super.getErrorAttributes(requestAttributes, includeStackTrace); 
      errorAttributes.remove("exception"); 
      return errorAttributes; 
     } 

    }; 
}