如何在@ExceptionHandler中获取BindException的root异常

时间:2017-01-10 07:47:00

标签: java spring validation spring-mvc bean-validation

我想处理@ControllerAdvice类中的所有控制器异常,但是当catch BindException时,我找不到根异常。

这是我的代码:

控制器:

@PostMapping
public ResponseEntity<UserDto> add(@Valid UserDto user) {
    return ResponseEntity.ok(user);
}

UserDto:

public class UserDto {

    private String name;
    private Gender gender;

    /*setter and getter*/
}

性别:

public enum Gender {

    FEMALE, MALE
}

转换器:

@Component
public class GenderConverter implements Converter<String, Gender> {

    @Override
    public Gender convert(String source) {
        try {
            return Gender.valueOf(source.toUpperCase());
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("Unknown gender value \"" +   source +
                    "\", gender value should be [female, male]");
        }
    }
}

当我发布gender = m 时,会出现异常消息:

org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'userDto' on field 'gender': rejected value [m]; codes [typeMismatch.userDto.gender,typeMismatch.gender,typeMismatch.org.tings.learning.spring.mvc.model.Gender,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userDto.gender,gender]; arguments []; default message [gender]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.tings.learning.spring.mvc.model.Gender' for property 'gender'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@javax.validation.constraints.NotNull org.tings.learning.spring.mvc.model.Gender] for value 'm'; nested exception is java.lang.IllegalArgumentException: Unknown gender value "m", gender value should be [female, male]]
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:118)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:160)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:129)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2508)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2497)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

2 个答案:

答案 0 :(得分:1)

我建议您阅读BeanPropertyBindingResult,根据以下文档:

  

错误和BindingResult接口的默认实现,用于   注册和评估JavaBean对象的绑定错误。

     

执行标准JavaBean属性访问,也支持嵌套   属性。通常,应用程序代码将与错误一起使用   接口或BindingResult接口。 DataBinder返回它   BindingResult通过DataBinder.getBindingResult()。

根据上面的描述,Spring验证框架在验证失败时抛出此错误,并且在您的代码中以及在包下定义的Gender类中发生类似的事情org.tings.learning.spring.mvc.model您发送的m Spring Gender无法找到db.getCollection('MyCollection'). find ({ "StartDateTime":{ $gte : ISODate("2016-12-08T00:00:00.0000Z") }, "Pages.PageEvents.PageEventDefinitionId": LUUID("dd6a6fdc-a96a-3f42-a824-49uuee741aa9") }); 枚举中的具体值,并要求您提供男性或女性作为输入:

根据错误日志:

  

无法从类型[java.lang.String]转换为type   [@ javax.validation.constraints.NotNull   org.tings.learning.spring.mvc.model.Gender] for value&#39; m&#39 ;;嵌套   异常是java.lang.IllegalArgumentException:未知的性别值   &#34; m&#34;,性别价值应为[女性,男性]]

答案 1 :(得分:0)