ktor简单配置rss

rss还是挺方便的,特别是阅读传统的博客

作者: lookroot

日期: 2025/08/15

最近有后台私信问我为啥我的博客rss订阅失效了,之前都是使用的成品博客或者使用了工具类里面的直接生成,今天抽空看了下结构很简单,快速实现一下。

当然欢迎使用rss订阅我的网络日志 点击订阅

推荐两个还挺好用的订阅工具

https://chromewebstore.google.com/detail/rss-feed-reader/pnjaodmkngahhkoihejjehlcdlnohgmp

https://app.follow.is/

RSS结构

最简单的结构,一个rss标签里面包含一个channel标签用来描述网站,item标签里面放最近更新的文章。

<rss version="2.0">
  <channel>
    <title>Lookroot的网络日志</title>
    <link>https://www.lookroot.cn</link>
    <description>这里是 lookroot的个人空间</description>
    <item>
      <title>文章xx标题</title>
      <link>https://www.lookroot.cn/notes/xxx</link>
      <description>文章xx描述</description>
      <pubDate>Sun, 03 Aug 2025 00:00:00 +0800</pubDate>
    </item>
  </channel>
</rss>

pubDate是GMT 格式时间,需要符合 RFC-822标准

EEE, dd MMM yyyy HH:mm:ss Z
  • EEE → 星期缩写(Mon, Tue, Wed, Thu, Fri, Sat, Sun)
  • dd → 两位日期(01–31)
  • MMM → 月份缩写(Jan, Feb, Mar, …, Dec)
  • yyyy → 4 位年份
  • HH:mm:ss → 24 小时时间
  • Z → 时区,通常写成 GMT+0000

Ktor代码示例

我使用的是ktor,springboot类似

    implementation("io.ktor:ktor-server-content-negotiation")
    implementation("io.ktor:ktor-serialization-kotlinx-xml")

配置

    install(ContentNegotiation) {
        xml()
    }

定义结构体

@XmlSerialName("rss", "", "")
@Serializable
data class Rss(
    val version: String = "2.0",
    val channel: Channel
)

@Serializable
@XmlSerialName("channel", "", "")
data class Channel(
    @XmlElement val title: String,
    @XmlElement val link: String,
    @XmlElement val description: String,
    val item: List<Item>
)

@Serializable
@XmlSerialName("item", "", "")
data class Item(
    @XmlElement val title: String,
    @XmlElement val link: String,
    @XmlElement val description: String,
    @XmlElement val pubDate: String
)
 get("/tool/rss") {

        val items = notesRepository.lastNotes(20)
            .map {
                Item(
                    it.title,
                    "https://www.lookroot.cn/notes/${it.uuid}",
                    it.desc ?: "",
                    convertTimestampToRssFormat(it.createTime!!)
                )
            }

        val rss = Rss(
            channel = Channel(
                title = "Lookroot的网络日志",
                link = "https://www.lookroot.cn",
                description = "这里是 lookroot的个人空间",
                item = items
            )
        )
        call.respond(rss)
    }

贴个秒时间戳转换RFC 822

fun convertTimestampToRssFormat(timestamp: Long): String {
    val instant = Instant.ofEpochSecond(timestamp)
    val formatter = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH)
        .withZone(ZoneId.of("Asia/Shanghai")) 
    return formatter.format(instant)
}

评论区

This is a dialog box!