科特林公司;Spring MVC-HTTP状态400-空
我有一个Kotlin科特林公司;Spring MVC-HTTP状态400-空,spring,spring-boot,kotlin,Spring,Spring Boot,Kotlin,我有一个Kotlin@RestController,我希望它在@RequestParam参数传递null的情况下返回400错误请求 示例: @RestController class Api() { @PostMapping("endpoint") fun endpoint(@DateTimeFormat(iso = DATE) @RequestParam date: LocalDate) { //do something } } 如果我请求发布/en
@RestController
,我希望它在@RequestParam
参数传递null
的情况下返回400
错误请求
示例:
@RestController
class Api() {
@PostMapping("endpoint")
fun endpoint(@DateTimeFormat(iso = DATE) @RequestParam date: LocalDate) {
//do something
}
}
如果我请求发布/endpoint?date
我会得到一个500
内部服务器错误,正文如下(缩短):
是否有任何方法可以使用一些附加库、配置或一些自定义代码来修复此问题,这些代码没有其他副作用,除了状态代码将是
400
Bad Request当验证失败时,默认情况下Spring将抛出IllegalArgumentException。Spring Boot应用程序中的每个异常在默认情况下都将被视为InternalServerError。
您可以通过添加如下函数来修改响应代码:
@RestController
类Api(){
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_请求)
IllegalArgumentException(IllegalArgumentException e)上的公共无效{
}
@后期映射(“端点”)
有趣的端点(@DateTimeFormat(iso=DATE)@RequestParam日期:LocalDate){
//做点什么
}
}
之后,您将在无效请求参数上获得400状态代码。我已经测试了您的代码,它没有明显的错误-按预期工作
curl -v -d "date=2020-10-01" http://localhost:8080/endpoint
* Trying ::1:8080...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> POST /endpoint HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.68.0
> Accept: */*
> Content-Length: 15
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 15 out of 15 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 200
< Content-Length: 0
< Date: Tue, 13 Oct 2020 07:04:21 GMT
<
* Connection #0 to host localhost left intact
curl-v-d“日期=2020-10-01”http://localhost:8080/endpoint
*正在尝试::1:8080。。。
*TCP_节点集
*已连接到本地主机(::1)端口8080(#0)
>POST/endpoint HTTP/1.1
>主机:本地主机:8080
>用户代理:curl/7.68.0
>接受:*/*
>内容长度:15
>内容类型:application/x-www-form-urlencoded
>
*完全发送上传:15个字节中的15个
*将捆绑包标记为不支持多用途
因此,我想:
application/x-www-form-urlencoded
,检查参数名称是否有拼写错误等Kotlin 1.4.*的以下工作。这不一定是最好的答案,因为不能保证Kotlin不会在将来的版本中更改消息的exoption类型。例如,当我最初问这个问题时,我使用的是1.3.*,例外情况是
IllegalArgumentException
。在1.4.*中,它已更改为NullPointerException
@ControllerAdvice
class KotlinNonNullParamHandling {
@ExceptionHandler
protected fun handleKotlinNonNullViolation(
exception: NullPointerException,
response: HttpServletResponse
) {
val nullParameter = exception.message?.startsWith("Parameter specified as non-null is null: ") == true
val restController = exception
.stackTrace
.getOrNull(0)
?.let { Class.forName(it.className) }
?.getAnnotation(RestController::class.java) != null
val status =
if (nullParameter && restController) HttpStatus.BAD_REQUEST
else HttpStatus.INTERNAL_SERVER_ERROR
response.sendError(status.value(), exception.message)
}
}
在假设它是400之前,我们检查异常
- 是一个
NullPointerException
- 具有以“指定为非null的参数为null:”开头的消息:
- 它是从类is RestController抛出的(否则可能是其他问题,例如通过反射将null发送到与web层无关的方法)
@ControllerAdvice
class KotlinNonNullParamHandling {
@ExceptionHandler
protected fun handleKotlinNonNullViolation(
exception: NullPointerException,
response: HttpServletResponse
) {
val nullParameter = exception.message?.startsWith("Parameter specified as non-null is null: ") == true
val restController = exception
.stackTrace
.getOrNull(0)
?.let { Class.forName(it.className) }
?.getAnnotation(RestController::class.java) != null
val status =
if (nullParameter && restController) HttpStatus.BAD_REQUEST
else HttpStatus.INTERNAL_SERVER_ERROR
response.sendError(status.value(), exception.message)
}
}