Skip to content
Server Plugin

Ktor Server におけるコンテンツ・ネゴシエーションとシリアライズ

必要な依存関係: io.ktor:ktor-server-content-negotiation

コード例: json-kotlinx

Native サーバー
Ktor は Kotlin/Native をサポートしており、追加のランタイムや仮想マシンなしでサーバーを実行できます。
のサポート: ✅

ContentNegotiation プラグインは、主に2つの目的を果たします。

  • クライアントとサーバー間でのメディアタイプのネゴシエーション。これには Accept および Content-Type ヘッダーを使用します。
  • 特定のフォーマットでのコンテンツのシリアライズ/デシリアライズ。Ktor は、JSON、XML、CBOR、ProtoBuf の各フォーマットを標準でサポートしています。

クライアント側では、Ktor はコンテンツのシリアライズ/デシリアライズのために ContentNegotiation プラグインを提供しています。

依存関係の追加

ContentNegotiation

ContentNegotiation を使用するには、ビルドスクリプトに ktor-server-content-negotiation アーティファクトを含める必要があります。

Kotlin
Groovy
XML

特定のフォーマットのシリアライザーには追加のアーティファクトが必要であることに注意してください。たとえば、kotlinx.serialization で JSON を使用するには ktor-serialization-kotlinx-json 依存関係が必要です。

シリアライズ

kotlinx.serialization コンバーターを使用する前に、Setup セクションの説明に従って Kotlin serialization プラグインを追加する必要があります。

JSON

JSON データをシリアライズ/デシリアライズするには、kotlinx.serialization、Gson、Jackson のいずれかのライブラリを選択できます。

ビルドスクリプトに ktor-serialization-kotlinx-json アーティファクトを追加します。

Kotlin
Groovy
XML

ビルドスクリプトに ktor-serialization-gson アーティファクトを追加します。

Kotlin
Groovy
XML

ビルドスクリプトに ktor-serialization-jackson アーティファクトを追加します。

Kotlin
Groovy
XML

XML

XML をシリアライズ/デシリアライズするには、ビルドスクリプトに ktor-serialization-kotlinx-xml を追加します。

Kotlin
Groovy
XML

XML シリアライズは jsNode ターゲットではサポートされていない ことに注意してください。

CBOR

CBOR をシリアライズ/デシリアライズするには、ビルドスクリプトに ktor-serialization-kotlinx-cbor を追加します。

Kotlin
Groovy
XML

ProtoBuf

ProtoBuf をシリアライズ/デシリアライズするには、ビルドスクリプトに ktor-serialization-kotlinx-protobuf を追加します。

Kotlin
Groovy
XML

ContentNegotiation のインストール

ContentNegotiation プラグインをアプリケーションに インストール するには、 指定された

モジュール
モジュールを使用すると、ルートをグループ化してアプリケーションを構造化できます。
内で install 関数に渡します。 以下のコードスニペットは、ContentNegotiation のインストール方法を示しています ...

  • ... embeddedServer 関数の呼び出し内。
  • ... Application クラスの拡張関数である明示的に定義された module 内。
kotlin
kotlin

シリアライザーの設定

Ktor は、JSONXMLCBOR の各フォーマットを標準でサポートしています。また、独自のカスタムシリアライザーを実装することもできます。

JSON シリアライザー

アプリケーションに JSON シリアライザーを登録するには、json メソッドを呼び出します。

kotlin
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.json.*

install(ContentNegotiation) {
    json()
}

json メソッドでは、JsonBuilder によって提供されるシリアライズ設定を調整することもできます。例:

kotlin

    install(ContentNegotiation) {
        json(Json {
            prettyPrint = true
            isLenient = true
        })

アプリケーションに Gson シリアライザーを登録するには、gson メソッドを呼び出します。

kotlin
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.serialization.gson.*

install(ContentNegotiation) {
    gson()
}

gson メソッドでは、GsonBuilder によって提供されるシリアライズ設定を調整することもできます。例:

kotlin
install(ContentNegotiation) {
    gson {
        registerTypeAdapter(LocalDate::class.java, LocalDateAdapter())
        setDateFormat(DateFormat.LONG, DateFormat.SHORT)
        setPrettyPrinting()
    }

アプリケーションに Jackson シリアライザーを登録するには、jackson メソッドを呼び出します。

kotlin
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.serialization.jackson.*

install(ContentNegotiation) {
    jackson()
}

jackson メソッドでは、ObjectMapper によって提供されるシリアライズ設定を調整することもできます。例:

kotlin
install(ContentNegotiation) {
    jackson {
        configure(SerializationFeature.INDENT_OUTPUT, true)
        setDefaultPrettyPrinter(DefaultPrettyPrinter().apply {
            indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance)
            indentObjectsWith(DefaultIndenter("  ", "
"))
        })
        registerModule(JavaTimeModule())  // java.time.* 型をサポート
    }
}

XML シリアライザー

アプリケーションに XML シリアライザーを登録するには、xml メソッドを呼び出します。

kotlin
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.xml.*

install(ContentNegotiation) {
    xml()
}

xml メソッドでは、XML シリアライズ設定にアクセスすることもできます。例:

kotlin
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.xml.*
import nl.adaptivity.xmlutil.*
import nl.adaptivity.xmlutil.serialization.*

install(ContentNegotiation) {
    xml(format = XML {
        xmlDeclMode = XmlDeclMode.Charset
    })
}

CBOR シリアライザー

アプリケーションに CBOR シリアライザーを登録するには、cbor メソッドを呼び出します。

kotlin
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.cbor.*

install(ContentNegotiation) {
    cbor()
}

cbor メソッドでは、CborBuilder によって提供される CBOR シリアライズ設定にアクセスすることもできます。例:

kotlin
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.cbor.*
import kotlinx.serialization.cbor.*

install(ContentNegotiation) {
    cbor(Cbor {
        ignoreUnknownKeys = true
    })
}

ProtoBuf シリアライザー

アプリケーションに ProtoBuf シリアライザーを登録するには、protobuf メソッドを呼び出します。

kotlin
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.protobuf.*

install(ContentNegotiation) {
    protobuf()
}

protobuf メソッドでは、ProtoBufBuilder によって提供される ProtoBuf シリアライズ設定にアクセスすることもできます。例:

kotlin
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.serialization.kotlinx.protobuf.*
import kotlinx.serialization.protobuf.*

install(ContentNegotiation) {
    protobuf(ProtoBuf {
        encodeDefaults = true
    })
}

カスタムシリアライザー

指定した Content-Type に対してカスタムシリアライザーを登録するには、register メソッドを呼び出す必要があります。以下の例では、application/json および application/xml データをデシリアライズするために 2 つの カスタムシリアライザー が登録されています。

kotlin
install(ContentNegotiation) {
    register(ContentType.Application.Json, CustomJsonConverter())
    register(ContentType.Application.Xml, CustomXmlConverter())
}

データの受信と送信

データクラスの作成

受信したデータをオブジェクトにデシリアライズするには、データクラスを作成する必要があります。例:

kotlin
data class Customer(val id: Int, val firstName: String, val lastName: String)

kotlinx.serialization を使用する場合は、このクラスに @Serializable アノテーションが付いていることを確認してください。

kotlin
import kotlinx.serialization.*
@Serializable
data class Customer(val id: Int, val firstName: String, val lastName: String)

以下の型のシリアライズ/デシリアライズは、kotlinx.serialization ライブラリによってサポートされています。

データの受信

リクエストのコンテンツを受信して変換するには、パラメータとしてデータクラスを受け取る receive メソッドを呼び出します。

kotlin

        post("/customer") {
            val customer = call.receive<Customer>()
            customerStorage.add(customer)
            call.respondText("Customer stored correctly", status = HttpStatusCode.Created)

リクエストの Content-Type は、リクエストを処理するための シリアライザー を選択するために使用されます。以下の例は、サーバー側で Customer オブジェクトに変換される JSON または XML データを含むサンプル HTTP クライアント リクエストを示しています。

HTTP
POST http://0.0.0.0:8080/customer
Content-Type: application/json

{
  "id": 3,
  "firstName": "Jet",
  "lastName": "Brains"
}
HTTP
POST http://0.0.0.0:8080/customer
Content-Type: application/xml

<Customer id="3" firstName="Jet" lastName="Brains"/>

完全な例はこちらにあります:json-kotlinx

データの送信

レスポンスでデータオブジェクトを渡すには、respond メソッドを使用できます。

kotlin
routing {
    get("/customer/{id}") {
        val id: Int by call.parameters
        val customer: Customer = customerStorage.find { it.id == id }!!
        call.respond(customer)

この場合、Ktor は Accept ヘッダーを使用して必要な シリアライザー を選択します。完全な例はこちらにあります:json-kotlinx

カスタムシリアライザーの実装

Ktor では、データのシリアライズ/デシリアライズのために独自の シリアライザー を作成できます。これを行うには、ContentConverter インターフェースを実装する必要があります。

kotlin
interface ContentConverter {
    suspend fun serialize(contentType: ContentType, charset: Charset, typeInfo: TypeInfo, value: Any): OutgoingContent?
    suspend fun deserialize(charset: Charset, typeInfo: TypeInfo, content: ByteReadChannel): Any?
}

実装例として GsonConverter クラスを参考にしてください。