gpt4 book ai didi

java - MockMvc 和流端点 - 流关闭后的附加字节

转载 作者:行者123 更新时间:2023-12-01 11:11:07 26 4
gpt4 key购买 nike

我在一个小型 Scala 应用程序中使用 spring-test 和 spring-boot 。 (对于冗长的介绍/简短的问题表示歉意!)

到目前为止,一切都很顺利,直到我决定修改其中一个端点以支持流式传输。为此,我将 HttpServletResponse 对象添加到我的请求处理程序中,并使用 Apache Commons 的 IOUtils.copy 复制源数据。

@RequestMapping(value = Array("/hello"), method = Array(RequestMethod.GET))
def retrieveFileForVersion(response:HttpServletResponse) = {
val is = getAnInputStream
val os = response.getOutputStream
try {
IOUtils.copy(is, os)
} finally {
IOUtils.closeQuietly(is)
os.flush()
IOUtils.closeQuietly(os)
}
}
}

这看起来效果相当好。我可以从端点检索二进制数据并验证其 MD5 校验和是否与源数据的 MD5 校验和匹配。

但是,我注意到在 spring-test 的 MockMvc 中使用 REST Controller 时,情况不再是这样。事实上,当通过 MockMvc 执行请求时,响应实际上比平常大了四个字节。因此,一些简单的断言会失败:

@Test
def testHello() = {

// ... snip ... read the binary file into a byte array
val bytes = IOUtils.toByteArray(...)

val result = mockMvc.perform(get("/hello")).andExpect(status.isOk).andReturn
val responseLength = result.getResponse.getContentAsByteArray.length

// TODO - find out why this test fails!
assert(responseLength == bytes.length, s"Response size: $responseLength, file size: ${bytes.length}")
assert(Arrays.equals(result.getResponse.getContentAsByteArray, bytes))
}

使用调试器,我能够确定 MockMvc 正在附加到响应 OutputStream,即使它已经使用 IOUtils.closeQuietly 关闭。事实上,它附加了请求处理程序的返回值,即 OutputStream 中的字节数(实际上来自 IOUtils.closeQuietly)。

为什么 MockMvc 在已关闭后还要追加到 OutputStream 中?这是一个错误,还是我错误地使用了该库?

最佳答案

根据返回类型、方法注释以及某些情况下的输入参数,可以以不同的方式解释 Controller 方法的返回值。

@RequestMapping 注释和引用文档中详细列出了这一点。对于您的流式处理情况,将 HttpServletResponse 的组合作为输入参数(您也可以顺便采用 OutputStream)和 void 作为返回类型,向 Spring MVC 表明您自己处理了响应。

关于java - MockMvc 和流端点 - 流关闭后的附加字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32363608/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com