Convert java.lang.Boolean to Scala Boolean

后端 未结 3 1550
醉梦人生
醉梦人生 2021-01-25 17:03

I am currently working on a Scala application which utilizes Spring-Boot and Swagger to send & receive REST-calls.

Swagger and Spring-Boot are pure Java-projects an

3条回答
  •  悲哀的现实
    2021-01-25 17:57

    By default Spring uses jackson-mapper to decode JSON request body to Java classes and encode Java classes to JSON response.

    Alternatively you can tell Spring to use ScalaObjectMapper which works well for scala data classes.

    
        com.fasterxml.jackson.module
        jackson-module-scala_2.12
        2.9.7
    
    

    Then configure Spring to use ScalaObjectMapper in WebMvcConfigurerAdapter. Example;

    import com.fasterxml.jackson.module.scala.DefaultScalaModule
    import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
    import scala.collection.JavaConverters._
    
    @EnableWebMvc
    @Configuration
    @PropertySource(Array("classpath:config/default.properties"))
    @ComponentScan(Array(
      "com.prayagupd"
    ))
    @Order(HIGHEST_PRECEDENCE)
    class MyAppConfig extends WebMvcConfigurerAdapter {
    
      override def extendMessageConverters(converters: java.util.List[HttpMessageConverter[_]]): Unit = {
        val encodeDecoderOpt = converters.asScala.collectFirst { case p: MappingJackson2HttpMessageConverter => p }
    
        val jacksonConverter = encodeDecoderOpt.getOrElse(new MappingJackson2HttpMessageConverter)
        jacksonConverter.setObjectMapper(Config.objectMapper)
    
        if (encodeDecoderOpt.isEmpty) // because converters is mutable
           converters.add(jacksonConverter)
      }
    }
    
    
    object Config {
    
      @Bean
      def objectMapper: ObjectMapper = {
        new ObjectMapper() with ScalaObjectMapper
      }.registerModule(DefaultScalaModule)
    }
    

    That should be it, now you can use pure scala data classes from Spring endpoint definition. Example

    @RestController
    @CrossOrigin(origins = Array("*"))
    @RequestMapping(value = Array("/"))
    class MyController @Autowired()(implicit val jacksonObjectMapper: ObjectMapper) {
      import MyController._
    
      @Async
      @RequestMapping(value = Array("/talk"), method = Array(RequestMethod.POST), consumes = Array(MediaType.APPLICATION_JSON_VALUE), produces = Array(MediaType.APPLICATION_JSON_VALUE))
      def talk(@RequestBody request: MyRequest): MyResponse = {
           // goes here
       }
    }
    
    //expose these in client jar if you want
    object MyController {
      final case class MyRequest(includeMovies: Boolean, includeTvShows: Boolean, somethingElse: List[String])
    
      final case class MyResponse(whatever: String)
    }
    

提交回复
热议问题