【问题标题】:Spring Boot @ExceptionHandler hide Exception NameSpring Boot @ExceptionHandler 隐藏异常名称
【发布时间】:2016-02-12 14:39:46
【问题描述】:

我正在使用 Spring Boot 1.3.X 并具有以下内容:

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

}

按预期工作。传递错误的参数时,会引发以下异常:

{
    "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 表示中排除 exception 字段?

【问题讨论】:

  • @JSONIgnore 能解决问题吗?

标签: java spring spring-mvc spring-boot


【解决方案1】:

您可以在控制器建议中获取 错误属性,然后只保留 可暴露字段。类似于以下内容:

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

【讨论】:

  • 这种作品,也就是EXPOSABLE_FIELDS里面没有列出的字段,从错误属性中去掉,但是返回的JSON还是和上面一样
  • exception 字段还在吗?
  • 是的,它仍然显示,尽管错误不再包含该字段。
  • 我会在接下来的几个小时内尝试一下,并回复您
【解决方案2】:

对于那些使用 spring boot 2.x.
自 2.0.0 版以来,ErrorAttrubutes 的默认实现是 DefaultErrorAttributes
DefaultErrorAttributes 尽可能提供异常堆栈跟踪。可以通过设置从答案中删除此字段:

server.error.include-stacktrace: never

【讨论】:

  • 是的,这适用于 Spring Boot 2.1.x,可能适用于 spring 1.x,你能告诉我们关于这个参数的文档在哪里吗?另外,据我所知,“从不”应该是默认值,但显然不是。
  • 很晚的答案,但我希望它会有用。链接到error properties
【解决方案3】:

我已经解决了这个bean-style。将以下 bean 定义添加到 REST 层配置替换 ErrorAttributes 在我的情况下使用已解决的问题,而没有任何异常处理的运行时代码。

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

    };
}

【讨论】:

  • 简单最好的解决方案
  • 相反,application.properties 中的一个简单属性可以解决问题:- server.error.include-exception=false
  • 如果您不想配置其他任何东西,并且可以在所有部署中进行适当的配置 - 似乎是更好的选择。但我个人不喜欢这样一个基本的东西的属性配置。
猜你喜欢
  • 1970-01-01
  • 2016-12-16
  • 2020-06-05
  • 2020-06-02
  • 2011-05-12
  • 1970-01-01
  • 2021-12-24
  • 2015-12-17
  • 1970-01-01
相关资源
最近更新 更多