当前位置: 首页 > 面试题库 >

Spring Rest错误处理@ControllerAdvice / @Valid

南宫云
2023-03-14
问题内容

在REST控制器中同时使用 @ControllerAdvice@Valid 批注时,遇到了麻烦。

我有一个声明如下的rest控制器:

@Controller
public class RestExample {

    ...

    /**
     * <XmlRequestUser><username>user1</username><password>password</password><name>Name</name><surname>Surname</surname></XmlRequestUser>
     * curl -d "@restAddRequest.xml" -H "Content-Type:text/xml" http://localhost:8080/SpringExamples/servlets/rest/add
     */
    @RequestMapping(value="rest/add", method=RequestMethod.POST)
    public @ResponseBody String add(@Valid @RequestBody XmlRequestUser xmlUser) {
        User user = new User();
        user.setUsername(xmlUser.getUsername());
        user.setPassword(xmlUser.getPassword());
        user.setName(xmlUser.getName());
        user.setSurname(xmlUser.getSurname());

        // add user to the database
        StaticData.users.put(xmlUser.getUsername(), user);
        LOG.info("added user " + xmlUser.getUsername());

        return "added user " + user.getUsername();
    }
}

还有一个ErrorHandler类:

@ControllerAdvice
public class RestErrorHandler extends ResponseEntityExceptionHandler {

    private static Logger LOG = Logger.getLogger(RestErrorHandler.class);


    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<Object> handleException(final RuntimeException e, WebRequest request) {
        LOG.error(e);

        String bodyOfResponse = e.getMessage();
        return handleExceptionInternal(e, bodyOfResponse, new HttpHeaders(), HttpStatus.CONFLICT, request);
    }
}

问题是,如果我在 RestExample.add* 方法中添加 “引发新的RuntimeException” ,则该异常由
RestErrorHandler 类正确处理。
***

但是,当向控制器卷曲无效请求时, RestErrorHandler 无法捕获验证程序抛出的异常,并且我收到 400 BadRequest
响应。(对于无效请求,我的意思是未指定用户名的xml请求)

请注意, XmlRequestUser 类由插件 maven-
jaxb2-plugin + krasa-jaxb-
tools
(pom.xml)自动生成:

<plugin>
    <groupId>org.jvnet.jaxb2.maven2</groupId>
    <artifactId>maven-jaxb2-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <schemaDirectory>src/main/xsd</schemaDirectory>
        <schemaIncludes>
            <include>*.xsd</include>
        </schemaIncludes>
        <args>
            <arg>-XJsr303Annotations</arg>
            <arg>-XJsr303Annotations:targetNamespace=http://www.foo.com/bar</arg>
        </args>
        <plugins>
            <plugin>
                <groupId>com.github.krasa</groupId>
                <artifactId>krasa-jaxb-tools</artifactId>
                <version>${krasa-jaxb-tools.version}</version>
            </plugin>
        </plugins>
    </configuration>
</plugin>

生成的类在用户名和密码字段上正确具有@NotNull批注。

我的 context.xml 非常简单,仅包含用于控制器的扫描程序并启用mvc:annotation-driven

<context:component-scan base-package="com.aa.rest" />
<mvc:annotation-driven />

有人知道如何在REST控制器中一起使用@ControllerAdvice和@Valid批注吗?

提前致谢。安东尼奥


问题答案:

您处在正确的轨道上,但是您需要覆盖handleMethodArgumentNotValid()而不是handleException()方法,例如

@ControllerAdvice
public class RestErrorHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(
            MethodArgumentNotValidException exception,
            HttpHeaders headers,
            HttpStatus status,
            WebRequest request) {

        LOG.error(exception);
        String bodyOfResponse = exception.getMessage();
        return new ResponseEntity(errorMessage, headers, status);
    }
}

从MethodArgumentNotValidException的JavaDoc中:

当对用@Valid注释的参数进行验证失败时,将引发异常。

换句话说,MethodArgumentNotValidException验证失败时将引发a
。它由所handleMethodArgumentNotValid()提供的方法处理,ResponseEntityExceptionHandler如果您想要自定义实现,则需要重写该方法。



 类似资料:
  • 和ErrorHandler类: 问题是,如果我在RestExample.add方法中添加一个“Throw new RuntimeException”,那么RestErrorHandler类将正确处理该异常。 但是,当将一个无效的请求向控制器卷取时,RestErrorHandler不会捕获验证器抛出的异常,而我会收到一个400BadRequest响应。(对于无效请求,我指的是未指定用户名的xml请求

  • 我正在使用Spring4开发一个RESTful应用程序。我想处理当一个POST请求不包含正文时的情况。我编写了以下自定义异常处理程序: 当它收到一个没有正文的POST时,这些方法不会被调用。相反,客户端得到一个带有400个坏请求HTTP状态和空正文的响应。有人知道怎么处理吗?

  • 我已经浏览了所有相关的帖子,但是我的@Controlller建议似乎没有处理从Controller类抛出的自定义异常。但是@Controller类中的@ExceptionHandler确实处理了异常。我不知道是什么错误。 网状物xml: dispatcher servlet。xml: @控制器建议等级: @ControllerAdvice与控制器位于同一个包中。

  • 我正在使用Spring Boot 1.5.9开发我的应用程序。我需要实现jwt身份验证,我使用了jjwt库。以下代码来自我的自定义身份验证安全筛选器,它继承自。在这里,我试图从令牌解析用户名,当自动解析用户名时,jwt会验证用户名,并检查令牌的过期时间。我调试了它,它可以工作,所以接下来我想向客户端应用发送正确的消息,说明身份验证失败的原因。我想抛出一个ExpiredJwtException,并使

  • 通过对错误类型实现 Display 和 From,我们能够利用上绝大部分标准库错误处理工具。然而,我们遗漏了一个功能:轻松 Box 我们错误类型的能力。 标准库会自动通过 Form 将任意实现了 Error trait 的类型转换成 trait 对象 Box<Error> 的类型(原文:The std library automatically converts any type that imp

  • 错误处理(error handling)是处理可能发生失败情况的过程。例如读取一个文件失败,然后继续使用这个失效的输入显然是有问题的。错误处理允许我们以一种显式的方式来发现并处理这类错误,避免了其余代码发生潜在的问题。 有关错误处理的更多内容,可参考官方文档的错误处理的章节。