【问题标题】:Client posting multipart form data客户发布多部分表单数据
【发布时间】:2019-12-11 10:05:59
【问题描述】:

我正在尝试创建一个用于测试我的控制器的客户端

控制器

@Secured(SecurityRule.IS_AUTHENTICATED)
@Controller
class InjuryController(private val userService: UserService, private val injuryService: InjuryService) {
...
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Post("/injuries/{id}/images")
    fun postImage(id: Long, file: CompletedFileUpload, principal: Principal): HttpResponse<*>? {
        ...
        return HttpResponse.ok(imageReference)
    }
...
}

客户

@Client("/")
interface InjuryClient {
    @Post("/injuries/{id}/images", produces = [MULTIPART_FORM_DATA])
    fun postImage(id: Long, body: MultipartBody, @Header authorization: String): ImageReference
}

测试

@Test
fun `Post an image an injury`() {
    // Given
    val description = "description"
    val occurredAt = LocalDateTime.now()
    val id = createInjury(description, occurredAt).id

    val toWrite = "test file"
    val file = File.createTempFile("data", ".txt")
    FileWriter(file).apply {
        write(toWrite)
        close()
    }

    val requestBody = MultipartBody.builder()
            .addPart("data",
                    file.name,
                    MediaType.TEXT_PLAIN_TYPE,
                    file
            ).build()

    // When
    val response = injuryClient.postImage(id, requestBody, authorization)

    // Then
    assertEquals("$id:${file.name}", response.key)
}

错误

The type java.util.LinkedHashMap is not a supported type for a multipart request body
io.micronaut.http.multipart.MultipartException: The type java.util.LinkedHashMap is not a supported type for a multipart request body
    at io.micronaut.http.client.DefaultHttpClient.buildMultipartRequest(DefaultHttpClient.java:2063)
    at io.micronaut.http.client.DefaultHttpClient.buildNettyRequest(DefaultHttpClient.java:1480)
    at io.micronaut.http.client.DefaultHttpClient.sendRequestThroughChannel(DefaultHttpClient.java:1599)
    at io.micronaut.http.client.DefaultHttpClient.lambda$null$27(DefaultHttpClient.java:1035)
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:570)
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:549)
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
    at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
    at io.netty.util.concurrent.DefaultPromise.setSuccess0(DefaultPromise.java:604)
    at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104)
    at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84)
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:300)
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:335)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:688)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:635)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:552)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:514)
    at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1044)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:834)

关于如何摆脱该错误的任何线索?

【问题讨论】:

    标签: kotlin micronaut micronaut-client


    【解决方案1】:

    客户端假定方法参数是主体的成员,而不是每个都代表整个主体。您可以通过在客户端中使用 @Body 注释 body 参数来实现所需的行为

    【讨论】:

    • 谢谢!另外值得一提的是,在上述问题中名为“数据”的部分名称必须与控制器方法中的参数名称相匹配。所以它只有在我将其更改为“文件”后才有效
    • @user672009 如果要保持方法参数名称相同,可以使用@Part("file")
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-08
    • 2015-10-31
    • 2019-11-19
    • 2017-06-06
    • 2016-11-11
    • 1970-01-01
    相关资源
    最近更新 更多