1

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

4

2 回答 2

1

有一个类接受 spring 初始化的 jackson objectmapper:

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())
            }
       }
    }
于 2019-03-14T14:31:07.580 回答
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;
  }
}

我完全明白这并没有给一个人他们可能想要的所有控制权,但它确实有效,它使您不必将 bean 自动连接到您使用燃料的每个地方。

于 2019-11-10T07:28:15.430 回答