Convert java.lang.Boolean to Scala Boolean

后端 未结 3 1512
醉梦人生
醉梦人生 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:55
    1. You don't need to write out java.lang.blah every time in

      ParamsAsJava(java.lang.Boolean.FALSE, java.lang.Boolean.TRUE)
      

      Just use

      ParamsAsJava(false, true)
      

      instead. Autoboxing hasn't gone anywhere.

    2. to get rid of toScala, define an implicit conversion in Params companion object:

      object Params {
        implicit def params_j2s(p: ParamsAsJava): Params = p.toScala()
      }
      

      now you can write:

      val test1: Params = ParamsAsJava(true, false)
      

      and, of course, if you don't define this variable in vacuum, but pass it to a method instead, the right type will be inferred automatically, and the object will be converted implicitly.

    3. No need to use parens () in def toScala(), the method has no side effects.

    0 讨论(0)
  • 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.

    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-scala_2.12</artifactId>
        <version>2.9.7</version>
    </dependency>
    

    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)
    }
    
    0 讨论(0)
  • 2021-01-25 18:01

    I used scala.Boolean box and unbox methods.

    0 讨论(0)
提交回复
热议问题