You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中Kotlin DTO作为@RequestBody触发400 Bad Request问题

问题描述

在混合Java与Kotlin的Spring Boot项目中,已引入并配置jackson-kotlin模块:

<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-kotlin</artifactId>
    <version>2.18.1</version>
</dependency>

配置类如下:

@Configuration
open class JacksonConfig {
    @Bean
    open fun objectMapper(): ObjectMapper {
        return ObjectMapper().registerKotlinModule()
    }
}

调用以下接口时:

@PostMapping("/test")
fun test(@RequestBody promptRequest: PromptRequest): ResponseEntity<String> {
    return ResponseEntity(promptRequest.prompt, HttpStatus.OK)
}

当PromptRequest为Kotlin数据类时:

data class PromptRequest (val prompt: String)

请求始终返回HTTP 400 Bad Request:

HTTP/1.1 400 
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/problem+json
Transfer-Encoding: chunked
Date: Tue, 12 Nov 2024 09:00:56 GMT
Connection: close

{
  "type": "about:blank",
  "title": "Bad Request",
  "status": 400,
  "detail": "Failed to read request",
  "instance": "/test",
  "properties": null
}

改为Java类则正常返回200:

public class PromptRequest {
    public String prompt;
}
HTTP/1.1 200 
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: text/plain;charset=UTF-8
Content-Length: 42
Date: Tue, 12 Nov 2024 09:05:08 GMT

input prompt

Response code: 200; Time: 3171ms (3 s 171 ms); Content length: 12 bytes (12 B)

已配置jackson-kotlin模块但问题依旧,服务器日志无报错,求原因及解决办法。

原因分析

问题出在自定义ObjectMapper的方式错误:直接new ObjectMapper()会完全替换Spring Boot默认配置好的ObjectMapper实例,丢失了Spring Boot自动配置中针对JSON序列化/反序列化的关键设置(比如消息转换器集成、属性命名策略、默认模块注册等)。虽然手动注册了Kotlin模块,但缺少其他必要配置,导致Kotlin数据类的反序列化失败。

另外,Kotlin数据类默认只有带参数的构造函数,Jackson Kotlin模块需要依赖这个构造函数进行反序列化,但如果ObjectMapper没有正确集成Spring上下文,可能无法正确识别构造函数参数。

解决方案

推荐以下几种正确配置方式:

方式1:使用Jackson2ObjectMapperBuilder构建(保留默认配置)

通过Spring提供的Jackson2ObjectMapperBuilder构建ObjectMapper,会保留所有Spring Boot默认配置,同时添加Kotlin模块:

@Configuration
open class JacksonConfig {
    @Bean
    open fun objectMapper(builder: Jackson2ObjectMapperBuilder): ObjectMapper {
        return builder
            .modulesToInstall(KotlinModule::class.java)
            .build()
    }
}

方式2:通过WebMvcConfigurer添加模块

不需要自定义ObjectMapper,直接配置消息转换器并注册Kotlin模块:

@Configuration
open class WebConfig : WebMvcConfigurer {
    override fun configureMessageConverters(converters: MutableList<HttpMessageConverter<*>>) {
        val converter = MappingJackson2HttpMessageConverter()
        converter.objectMapper.registerModule(KotlinModule())
        converters.add(0, converter)
    }
}

方式3:删除自定义配置(最推荐)

在Spring Boot项目中,只要引入jackson-module-kotlin依赖,Spring Boot会自动将Kotlin模块注册到默认的ObjectMapper中。直接删除自定义的JacksonConfig类,重启项目即可解决问题。

验证步骤
  1. 删除自定义的JacksonConfig配置类
  2. 确保jackson-module-kotlin依赖存在
  3. 重启项目,用Kotlin数据类测试接口,请求体使用标准JSON格式(如{"prompt": "input prompt"}),并设置请求头Content-Type: application/json

内容的提问来源于stack exchange,提问作者janssen-dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:48:22