当前位置: 首页 > 知识库问答 >
问题:

当@控制器返回反应类型(Mono)时,如何设置@ExceptionHandler提供的响应的状态代码?

阳念
2023-03-14

当@控制器返回反应类型(Mono)时,如何设置@ExceptionHandler提供的响应的状态代码?

这似乎是不可能的,通过返回响应实体或注释@ExceptionHandler方法与@响应状态。

显示问题的最低限度测试(请注意,响应正文和内容类型已正确验证,而状态代码应为INTERNAL\u SERVER\u ERROR时为OK):

class SpringWebMvcWithReactiveResponseTypeExceptionHandlerCheckTest {

    @RestController
    @RequestMapping("/error-check", produces = ["text/plain;charset=UTF-8"])
    class ExceptionHandlerCheckController {

        @GetMapping("errorMono")
        fun getErrorMono(): Mono<String> {
            return Mono.error(Exception())
        }
    }

    @ControllerAdvice
    class ErrorHandler : ResponseEntityExceptionHandler() {

        @ExceptionHandler(Exception::class)
        @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
        fun handleException(ex: Exception): ResponseEntity<*> = ResponseEntity
            .status(HttpStatus.INTERNAL_SERVER_ERROR)
            .contentType(MediaType.APPLICATION_PROBLEM_JSON)
            .body(mapOf("key" to "value"))
    }

    val mockMvc = MockMvcBuilders
        .standaloneSetup(ExceptionHandlerCheckController())
        .setControllerAdvice(ErrorHandler())
        .build()

    @Test
    fun `getErrorMono returns HTTP Status OK instead of the one set by an ExceptionHandler`() {
        mockMvc.get("/error-check/errorMono")
//            .andExpect { status { isInternalServerError() } }
            .andExpect { status { isOk() } }
            .asyncDispatch()
            .andExpect {
                content {
                    contentType(MediaType.APPLICATION_PROBLEM_JSON_VALUE)
                    json("""
                    {
                      "key": "value"
                    }
                    """,strict = true
                    )
                }
            }
    }
}

(build.gradle.kts摘录显示了相关依赖项):

plugins: {
  id("org.springframework.boot") version "2.4.5"
  id("io.spring.dependency-management") version "1.0.11.RELEASE"
}

dependencies {
  implementation("org.springframework.boot:spring-boot-starter-web")
  implementation("org.springframework.boot:spring-boot-starter-webflux")
  testImplementation("org.springframework.boot:spring-boot-starter-test") 
}

共有1个答案

樊奇思
2023-03-14

问题是必须在. asyncDispatch()之后调用. andExplect{status...(与内容类型和正文一样)。似乎超文本传输协议状态已更新。可能这实际上是异步请求的超文本传输协议标准的一部分,但我怀疑这是底层MockHttpServletACK的错误。

 类似资料:
  • 我正在使用Junit 5和mockito进行一些单元测试。 要被模拟的方法调用如下。它返回一个Mono并接受两个String参数。 我嘲笑它如下 这会产生一个空指针,如下所示

  • 我编写了以下控制器方法: 当我在浏览器中请求此方法时,我看到以下内容: 我实现服务器端错误还是客户端问题? 更新NJNEX答案。 如果我想在控制器方法中实现以下逻辑,我应该怎么做:

  • 因为它创建了一个新的资源,所以如果它返回状态代码201是合适的,但目前它返回200。 我发现如何设置状态代码的唯一方法是让方法返回一个并在那里设置它,但我确实不希望我的所有接口返回一个泛型响应,而不是实际的响应对象(在本例中是)。

  • 问题内容: 我有一个API调用,我需要对其进行一些检查并可能返回各种状态代码。我不需要自定义视图或任何东西,我只需要返回正确的代码。如果用户未通过适当的凭据,则需要返回401状态。如果他们尚未发送受支持的请求格式,则需要返回400状态。 因为它是一个API,所以我真正想做的就是设置响应状态并以一条简单的愚蠢消息退出,该消息说明请求失败的原因(可能使用)。刚好足以完成工作,但我还无法使其正常工作。我

  • 我使用了来自org的openapi生成器maven插件。在我的Spring Boot项目中启用了被动配置的openapitools。我的一个endpoint返回一个列表体响应,该响应自动生成为Mono 如何使用WebTestClient在联调中测试endpoint控制器的主体? 如果我尝试这样做,它不会起作用,因为我接收到的是通量,而不是预期的dto对象。

  • 我有一个Restendpoint,如果没有产品,它将返回204,以及以下通用角度服务: 和 但是,当服务生成 204 代码时,我收到以下错误: TypeError:无法读取null的属性“status” 这怎么可能发生?如果 API 以 204 响应,为什么整个响应为空?