java - 如何在@ExceptionHandler 中获取 BindException 的根异常

标签 java spring validation spring-mvc bean-validation

我想在@ControllerAdvice 类中处理所有 Controller 异常,但是当捕获BindException 时,我找不到根异常。

这是我的代码:

Controller :

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

最佳答案

我建议您阅读有关 BeanPropertyBindingResult 的内容,根据以下文档:

Default implementation of the Errors and BindingResult interfaces, for the registration and evaluation of binding errors on JavaBean objects.

Performs standard JavaBean property access, also supporting nested properties. Normally, application code will work with the Errors interface or the BindingResult interface. A DataBinder returns its BindingResult via DataBinder.getBindingResult().

根据上面的描述,Spring验证框架每当验证失败时抛出此错误并且您的代码以及Gender 中发生了类似的事情包下定义的类 org.tings.learning.spring.mvc.model您正在发送 mSpring无法在 Gender 中找到特定值枚举并要求您将男性或女性作为输入:

根据错误日志:

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]]

关于java - 如何在@ExceptionHandler 中获取 BindException 的根异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41563660/

相关文章:

java - 自动添加千位分隔符作为数字输入不起作用

java - 用于完成点击次数共享首选项的语法

java - 如何将 CXF 从 2.7 迁移到 3.0?

javascript - 使用查询根据单选按钮动态添加/删除输入字段

asp.net - 如何在VS中为ASPX运行ASP.NET验证?

java - 切换案例错误验证

java - java.io.writer 的 append 和 write 方法有什么区别?

java - 多少类太多了?什么时候适合添加新类?

java - Spring 应用程序中的 CouchBase 日志记录

java - 简单 : convertAndSendToUser Where do I get a username?