Проблема десериализации Json, вызывающая лямбду AWS, написанную на Kotlin, с использованием Spring Cloud Function - PullRequest
0 голосов
/ 23 сентября 2018

Я развернул AWS Lambda, написанный на Kotlin, используя Spring Cloud Function.Когда я тестирую его с запросом json

{"id":"1",
 "name":"John"
}

, я получаю следующую ошибку:

"No suitable constructor found for type [simple type, class step.Request]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)\n at [Source: lambdainternal.util.NativeMemoryAsInputStream@4b53f538; line: 1, column: 2]",
        "errorType": "com.fasterxml.jackson.databind.JsonMappingException",
        "stackTrace": [
          "com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)",
          "com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1106)",
          "com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:296)",
          "com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:133)",
          "com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1511)",
          "com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1102)"

Если я запускаю свое приложение локально и выполняю запрос POST на http://localhost:8080/function стот же запрос json, он работает нормально.

Хотя я знаю, что могу добиться этого, добавив аннотации @JsonCreator и @JsonProperty в класс Request, но я хочу избежать этого и хочу понять причину сбоя при запускеэто как лямбда.

Любые входы очень ценятся.Заранее спасибо

Соответствующий код выглядит следующим образом:

package step

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Primary
import org.springframework.stereotype.Component
import java.util.function.Function


@SpringBootApplication
class F1 {

    @Bean
    @Primary
    fun objectMapper() = ObjectMapper().apply {
        this.registerModule(KotlinModule())
    }
}

data class Request (val id: String, val name: String)
data class Response(val message: String)

class Handler : SpringBootRequestHandler<Request, Response>()

@Component("function")
class Function :
    Function<Request, Response> {
    override fun apply(t: Request): Response {

        println("$t")
        return Response("${t.id}:${t.name}")
    }

}

fun main(args: Array<String>) {
    SpringApplication.run(F1::class.java, *args)

}

build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
import org.jetbrains.kotlin.noarg.gradle.NoArgExtension

buildscript {
    var springBootVersion: String by extra
    springBootVersion = "2.0.0.RELEASE"

    var wrapperVersion: String by extra
    wrapperVersion = "1.0.12.BUILD-SNAPSHOT"

    var shadowVersion: String by extra
    shadowVersion = "2.0.1"

    var kotlinVersion: String by extra
    kotlinVersion = "1.2.70"

    repositories {
        mavenCentral()
        maven("https://repo.spring.io/snapshot")
        maven("https://repo.spring.io/milestone")
    }

    dependencies {
        classpath(kotlinModule("gradle-plugin", kotlinVersion))
        classpath("com.github.jengelman.gradle.plugins:shadow:$shadowVersion")
        classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion")
        classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
        classpath("org.jetbrains.kotlin:kotlin-noarg:$kotlinVersion")
    }
}

var springCloudVersion: String by extra
springCloudVersion = "1.0.0.BUILD-SNAPSHOT"

var awsLambdaVersion: String by extra
awsLambdaVersion = "1.1.0"

var awsLambdaEventsVersion: String by extra
awsLambdaEventsVersion = "1.2.1"

extra["reactor.version"] = "3.1.7.RELEASE"

plugins {
    kotlin("jvm") version "1.3.0-rc-57"
    java
    maven
    idea
}

group = "stepfunctions"
version = "1.0-SNAPSHOT"

apply {
    plugin("maven")
    plugin("kotlin")
    plugin("kotlin-spring")
    plugin("org.jetbrains.kotlin.plugin.noarg")
    plugin("io.spring.dependency-management")
    plugin("org.springframework.boot")
    plugin("com.github.johnrengelman.shadow")
}

repositories {
    mavenLocal()
    mavenCentral()
    maven("https://repo.spring.io/snapshot")
    maven("https://repo.spring.io/milestone")
    maven { setUrl("http://dl.bintray.com/kotlin/kotlin-eap") }

}

dependencies {

    compile("org.jetbrains.kotlin", "kotlin-stdlib-jdk8", extra.get("kotlinVersion") as String)
    compile("org.jetbrains.kotlin", "kotlin-reflect", extra.get("kotlinVersion") as String)
    compile("org.springframework.cloud", "spring-cloud-function-adapter-aws", extra.get("springCloudVersion") as String)
    compile("org.springframework.cloud", "spring-cloud-starter-function-web", extra.get("springCloudVersion") as String)
    compile("io.github.microutils:kotlin-logging:1.5.4")
    compile("com.fasterxml.jackson.module:jackson-module-kotlin:2.9.0")

    compileOnly("com.amazonaws:aws-lambda-java-events:$awsLambdaEventsVersion")
    compileOnly("com.amazonaws", "aws-lambda-java-core", extra.get("awsLambdaVersion") as String)

}

tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = "1.8"
}

tasks.withType<ShadowJar> {
    classifier = "function"
    manifest {
        attributes(
            mapOf(
                "Start-Class" to "step.F1",
                "Main-Class" to "step.F1"
            )
        )
    }

    dependencies {
        exclude("org.springframework.cloud:spring-cloud-function-web:1.0.0.BUILD-SNAPSHOT")
    }

    mergeServiceFiles()
    append("META-INF/spring.handlers")
    append("META-INF/spring.schemas")
    append("META-INF/spring.tooling")
    transform(PropertiesFileTransformer::class.java) {
        paths = listOf("META-INF/spring.factories")
        mergeStrategy = "append"
    }
}
tasks.getByPath("assemble").dependsOn("shadowJar")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...