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

如何让JSON响应中实体属性createdAt显示为数据库列名created_at?

问题:如何让JSON响应使用数据库列名(如created_at)而非实体属性名?

我在从数据库获取实体后序列化JSON响应时,希望输出的字段名使用数据库列名(比如created_at),但当前返回的是实体属性名createdAt。相关代码如下:

GET请求处理代码

get("/v1/posts") {
        val posts= service.getAll()

        val mapper: ObjectMapper = JsonMapper.builder()
            .addModule(JavaTimeModule())
            .addModule(KtormModule())
            .build()

        val json = mapper.writeValueAsString(posts)
        call.respond(HttpStatusCode.OK, json)
}

当前JSON输出

{
    "id": 1,
    "title": "Some Title",
    "description": "some text...",
    "createdAt": [
        2018,
        9,
        16,
        1,
        1,
        36,
        399357000
    ]
}

实体与表定义

interface Post: Entity<Post> {
    companion object : Entity.Factory<Post>()
    val id: Int
    var title: String
    var description: String
    var createdAt: LocalDateTime
}

object Posts: Table<Post>("posts") {
    val id = int("id").primaryKey().bindTo { it.id }
    val title = varchar("title").bindTo { it.title }
    val description = varchar("description").bindTo { it.description }
    val createdAt = datetime("created_at").bindTo { it.createdAt }
}

val Database.posts get() = this.sequenceOf(Posts)

Application配置

fun Application.module() {
    install(ContentNegotiation) {
        json()
        jackson {
            configure(SerializationFeature.INDENT_OUTPUT, true)
            setDefaultPrettyPrinter(DefaultPrettyPrinter().apply {
                indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance)
                indentObjectsWith(DefaultIndenter("  ", "\n"))
            })
            registerModule(JavaTimeModule())  // support java.time.* types
            configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
        }
    }

    configureRouting()
}

需要解决的是让JSON中的createdAt显示为created_at。


解决方案

方法1:全局配置Jackson蛇形命名策略

Jackson默认使用实体属性名,要自动将驼峰式转换为蛇形命名(如createdAt→created_at),只需在Application.kt的Jackson配置中添加命名策略:

fun Application.module() {
    install(ContentNegotiation) {
        json()
        jackson {
            configure(SerializationFeature.INDENT_OUTPUT, true)
            setDefaultPrettyPrinter(DefaultPrettyPrinter().apply {
                indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance)
                indentObjectsWith(DefaultIndenter("  ", "\n"))
            })
            registerModule(JavaTimeModule())
            configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
            // 启用蛇形命名策略
            propertyNamingStrategy = PropertyNamingStrategies.SNAKE_CASE
        }
    }

    configureRouting()
}

同时删除路由中手动创建的ObjectMapper,直接返回实体即可,Ktor会复用全局配置的Jackson:

get("/v1/posts") {
    val posts = service.getAll()
    call.respond(HttpStatusCode.OK, posts)
}

此方法同时解决日期序列化为数组的问题,因为全局配置已正确处理Java时间类型。

方法2:为单个字段指定JSON别名

若无需全局修改命名策略,仅针对特定字段设置别名,可在实体属性上添加@JsonProperty注解:

interface Post: Entity<Post> {
    companion object : Entity.Factory<Post>()
    val id: Int
    var title: String
    var description: String
    @JsonProperty("created_at")
    var createdAt: LocalDateTime
}

这种方式更灵活,适合仅需修改个别字段的场景。

方法3:利用Ktorm模块的列名序列化特性

Ktorm的KtormModule可根据表定义中的数据库列名序列化实体,只需将其注册到全局Jackson配置:

fun Application.module() {
    install(ContentNegotiation) {
        json()
        jackson {
            // 保留原有配置
            configure(SerializationFeature.INDENT_OUTPUT, true)
            setDefaultPrettyPrinter(DefaultPrettyPrinter().apply {
                indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance)
                indentObjectsWith(DefaultIndenter("  ", "\n"))
            })
            registerModule(JavaTimeModule())
            configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
            // 注册Ktorm模块
            registerModule(KtormModule())
        }
    }
}

路由代码直接返回实体,无需手动序列化:

get("/v1/posts") {
    val posts = service.getAll()
    call.respond(HttpStatusCode.OK, posts)
}

Ktorm模块会自动匹配表定义中的列名,将createdAt序列化为created_at。


内容的提问来源于stack exchange,提问作者user21225362

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 01:07:52