将Spring的Objectmapper与Kotlin燃料一起使用

时间:2018-12-14 10:43:33

标签: spring kotlin kotlin-fuel

我在我的kotlin spring应用程序中使用燃料进行HTTP集成,有一种方法可以使用Jackson进行JSON序列化/反序列化。 但是,映射器是FuelJackson.kt中的val。 有没有一种方法可以将Spring配置为Jackson的Jackson Objectmapper定义为bean?

2 个答案:

答案 0 :(得分:1)

有一个类接受弹簧初始化的杰克逊对象映射器:

class FuelDeserializer(val objectMapper: ObjectMapper) {
inline fun <reified T : Any> deserialize() = object : ResponseDeserializable<T> 
{
        override fun deserialize(inputStream: InputStream): T? {
            return objectMapper.readValue(inputStream)
        }

        override fun deserialize(reader: Reader): T? {
            return objectMapper.readValue(reader)
        }

        override fun deserialize(bytes: ByteArray): T? {
            return objectMapper.readValue(bytes)
        }

        override fun deserialize(content: String): T? {
            return objectMapper.readValue(content)
        }
    }
}

此类可以作为bean添加到您的配置中

@Configuration
class ObjectMapperConfiguration {
    @Bean
    fun objectMapper(builder: Jackson2ObjectMapperBuilder): ObjectMapper {
        val objectMapper = builder.build<ObjectMapper>()
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
        objectMapper.findAndRegisterModules()
        return objectMapper
    }

    @Bean
    fun fuelDeserializer(objectMapper: ObjectMapper): FuelDeserializer {
        return FuelDeserializer(objectMapper)
    }
}

用法就是这样

@Controller
class PdfGeneratorApi( 
    val fuelDeserializer: FuelDeserializer
) {

    fun postSomething(): ResponseEntity<?> {
        "http://exampl.com"
            .httpPost()
            .body("Something to post")
            .responseObject<MyObject>(fuelDeserializer.deserialize()) {_, _, result -> 
            when (result) {
                is Result.Failure -> logger.warn(result.getException()) { "Failure while posting" }
                is Result.Success -> ResponseEntity.ok(result.get())
            }
       }
    }

答案 1 :(得分:1)

FuelJackson.kt中的defaultMapper是一个val,但这并不意味着您无法向其注册模块。

您可以在配置类中执行类似的操作。

@Configuration
public class JacksonConfiguration {

  @Bean
  /**
   * Single place to get object mapper specific modules registered.
   *
   * @return ObjectMapper with necessary modules registered
   */
  public ObjectMapper jacksonObjectMapper() {
    var mapper = new ObjectMapper();
    mapper.registerModule(new Jdk8Module());
    mapper.registerModule(new JavaTimeModule());
    mapper.registerModule(new KotlinModule());
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    // it won't be the exact same object mapper used throughout 
    // your spring application, but you can make the fuel mapper 
    // match right here in the bean. 
    FuelJacksonKt.getDefaultMapper().registerModule(new JavaTimeModule());

    return mapper;
  }
}

我完全明白这并不能给人一个他们可能想要的所有控制权,但是它确实起作用,并且使您不必将咖啡豆自动接线到每个使用燃料的地方。