Skip to content
Server Plugin

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

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

コード例: json-kotlinx

ネイティブサーバー
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コンバーターを使用する前に、セットアップセクションで説明されているように、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のインストール

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

モジュール
モジュールを使用すると、ルートをグループ化してアプリケーションを構造化できます。
内のinstall関数にContentNegotiationプラグインを渡します。 以下のコードスニペットは、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())  // support java.time.* types
    }
}

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
@Serializable

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

kotlin
import kotlinx.serialization.*
import io.ktor.server.util.getValue

@Serializable

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

データの受信

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

kotlin

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

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

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クラスを参照してください。