自定义Spring ConversionFailedException错误HTTP状态

时间:2016-02-27 02:35:57

标签: spring spring-mvc parameters enums http-status-codes

我有一个枚举类:

class enum Type {
   LOCAL, REMOTE
}

我有一个接受enum作为GET参数的API

@RequestMapping(method = RequestMethod.GET, location="item", params = "type")
public Item[] get(Type type) {
...

当客户使用有效值调用API时,例如GET /item?type=LOCALGET /item?type=REMOTE,它可以正常工作。如果客户提供type的无效值,例如GET /item?type=INVALID_TYPE,然后Spring生成500 Internal Server Error。我想将其转换为400 Bad Request验证错误,可能会为客户端添加有用的信息。我更喜欢重用内置类型转换器,因为在工作中很好,只想更改一种错误的HTTP类型,只需最少的更改。

2 个答案:

答案 0 :(得分:2)

我相信如果您向@ControllerAdvice添加正确的例外,您可以自定义响应。在这种情况下,我发现MethodArgumentTypeMismatchException是有问题的。

@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public void methodArgumentTypeMismatchException(final HttpServletResponse response) throws IOException {
    response.sendError(BAD_REQUEST.value());
}

答案 1 :(得分:-1)

为什么会这样?

我会考虑查看有关@ControllerAdvice和/或@ExceptionHandler注释的示例here。您遇到的错误正在发生,因为我相信,Spring会尝试从“INVALID_TYPE”字符串构造一个Type,并在无法从中创建Type时收到错误 - 因为“INVALID_TYPE”不是可用值之一。

我该怎么办?

你要做的是在你的枚举中添加一个字符串构造函数,以便更正确地知道如何创建其中一个枚举对象,然后检查输入以查看它是否有效。如果它无效,则抛出自定义异常。然后,在@ControllerAdvice中,您可以自定义响应的HTTP状态代码。

然后可以使用以下内容处理异常:

@ControllerAdvice
class GlobalControllerExceptionHandler {
    @ResponseStatus(HttpStatus.BAD_REQUEST)  // 409
    @ExceptionHandler(MyCustomException.class)
    public void handleConflict() {
        // handle the exception response, if you need information about the
        // request, it should be able to be attached to the custom exception
    }
}

枚举看起来像这样:

public enum Type{

    LOCAL("LOCAL"), 
    REMOTE("REMOTE"); 

    private String type;

    private Type(String type) {
        if(type.equals("LOCAL") || type.equals("REMOTE")) {
            this.type = type;
        } else {
            throw new MyCustomException();
        }
    }

    public String getType() {
        return url;
    }

}