我的控制器中的端点配置如下:
@RequestMapping(value = "/users/{userId}/data", method = RequestMethod.GET)
public void getUserData(@PathVariable("userId") @Valid @NotNull Integer userId, HttpServletRequest request) {
}
如果客户端向此端点发送空白userId
的请求,我假设Spring将URL解释为/users//data
,因为抛出了此异常:
2017-03-03 11:13:41,259 [[ACTIVE] ExecuteThread:'3'表示队列: 'weblogic.kernel.Default(self-tuning)'] ERROR类 com.xxxx.web.controller.custom.ExceptionHandlingController: 抛出RuntimeException: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: 无法将'java.lang.String'类型的值转换为所需类型 'java.lang.Integer中';嵌套异常是 java.lang.NumberFormatException:对于输入字符串:“data”
处理此用例的最佳方法是什么?我担心将userId
转换为String并捕获异常,这似乎是一个黑客攻击。我也不想依赖客户端总是发送正确的请求。我目前正在使用Spring-Boot v1.2.6.RELEASE,如果我知道将修复它,我愿意升级版本。
答案 0 :(得分:1)
您可以创建一个类来处理全局异常,并使用@ControllerAdvice对其进行注释。
@ControllerAdvice
public class CustomRestExceptionHandler extends ResponseEntityExceptionHandle {
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<Object> handleMethodArgumentTypeMismatch(
MethodArgumentTypeMismatchException ex, WebRequest request) {
//Handle your exception here...
}
}
以下是关于如何使用@ControllerAdivce
做很多事情的好文章http://www.baeldung.com/global-error-handler-in-a-spring-rest-api
答案 1 :(得分:0)
您的请求映射中存在冲突。
您很可能还拥有/users/{userId}
的GET映射。这是应用的映射,而不是您问题中的映射。
问题是您通过单斜杠请求/users//data
,Web服务器automatically replaces双斜杠。结果请求与此模式/users/{userId}
完全匹配,但与您发布的模式不匹配。最后,spring无法将data
转换为整数。
如果您删除/users/{userId}
(仅出于测试原因),您可能会收到404错误代码请求相同的网址。
编辑:
实际上,您不应该关心有人向您的REST API发送错误的请求。 REST API是一份合同,双方都应遵守此合同。作为后端点,您应该只处理请求并提供适当的错误代码和良好的描述,以防请求错误。 data
永远不是一个正确的用户ID,请确保此信息包含在响应中,而不是那些技术内容。
可能的解决方案之一是使用模式验证ID。 在您的情况下,它将如下所示:
@RequestMapping(value = "/users/{userId:\\d+}/data", method = GET)
@RequestMapping(value = "/users/{userId:\\d+}", method = GET)
在这种情况下,spring会自动过滤非数字ID并为它们提供HTTP 404。