GSON Kotlin And TypeToken Retrofit

"Something about GSON Kotlin And TypeToken Retrofit."

Posted by ML on March 23, 2019 字数:5137

浏览量:

“Yeah It’s on. ”

GSON Kotlin And TypeToken Retrofit

Gson 解析对象

  • Kotlin中:
    • 第一种方式: 

          val turnsType = object : TypeToken<List<Turns>>() {}.type
          val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType) 
      
    • 第二种方式: 使用泛型

         inline fun <reified T> genericType() = object: TypeToken<T>() {}.type
      //list对象    
         val turnsType = genericType<List<Person>>()
         val turns = Gson().fromJson<List<Person>>(jsonSTR, turnsType) 
      //对象    
         val turnsType = genericType<Person>()
         val turns = Gson().fromJson<Person>(jsonSTR, turnsType) 
      

Springboot 返回图片

  • 1.在springboot的application配置类中添加以下代码,使其支持图片返回,不然会报错,获取不到图片
      @Bean
         public BufferedImageHttpMessageConverter bufferedImageHttpMessageConverter() {
             return new BufferedImageHttpMessageConverter();
         }
    
  • 2.controller中主要配置GetMapping的produces,使其允许返回图片类型
        @GetMapping("/getBingPic", produces = [MediaType.IMAGE_JPEG_VALUE])
         @ResponseBody
         fun bingPic(): BufferedImage {
             val item = getUrls()[0] as ImageInfo
             LogUtil.info(item.url)
             val url = URL(item.url)
             val input = BufferedInputStream(url.openStream())
             return ImageIO.read(input)
         }
    
  • 3.注意如果是网络图片应该使用另一种方式读写,否则会出现 (文件名、目录名或卷标语法不正确。)
      //网络路径读写
      val url = URL(path)
      val input = BufferedInputStream(url.openStream())
      return ImageIO.read(input)
      //本地路径
      return ImageIO.read(FileInputStream(File(path)))
    

Retrofit 请求网络

  • 工具类
      import okhttp3.OkHttpClient
      import okhttp3.logging.HttpLoggingInterceptor
      import retrofit2.Retrofit
      import retrofit2.converter.gson.GsonConverterFactory
      import retrofit2.converter.scalars.ScalarsConverterFactory
      import java.util.concurrent.TimeUnit
      object HttpCreator {
        
          private var BASE_URL: String = ""
          private val httpClient = OkHttpClient.Builder()
        
          private var DEFAULT_TIMEOUT: Long = 20L
          private val builder = Retrofit.Builder()
                  .addConverterFactory(ScalarsConverterFactory.create())
                  .addConverterFactory(GsonConverterFactory.create())
        
          /***
           * 设置连接超时时间默认20s,此函数需在create()之前调用
           * @param time
           */
          fun setTimeOut(time: Long): HttpCreator {
              DEFAULT_TIMEOUT = time
              httpClient.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
              return this
          }
        
          /**
           * 设置base url
           * @param url
           */
          fun setBaseURL(url: String): HttpCreator {
              BASE_URL = url
              builder.baseUrl(BASE_URL)
              return this
          }
        
          fun buildClient(): Retrofit.Builder = builder.client(httpClient.build())
        
          /**
           * 是否设置链接日志过滤,此函数需在create()之前调用
           * @param isUse
           */
          fun setIsUseLoggingInterceptor(isUse: Boolean): HttpCreator {
              httpClient.addInterceptor(
                      HttpLoggingInterceptor(HttpLoggingInterceptor
                              .Logger { message ->
                                  //打印retrofit日志
                                  println("RetrofitLog" + "retrofitBack = $message")
                              }
                      )
                              .setLevel(
                                      if (isUse)
                                          HttpLoggingInterceptor.Level.BODY
                                      else
                                          HttpLoggingInterceptor.Level.NONE
                              )
              )
              return this
          }
        
          /***
           * 创建实例
           * @param serviceClass 接口类
           * @exception setBaseURL(url) must be called first.
           */
          fun <T> create(serviceClass: Class<T>): T = if (BASE_URL == "")
              throw RuntimeException("setBaseURL(url) must be called first.") as Throwable
          else {
              buildClient().build().create(serviceClass)
          }
      }
        
    
  • 使用
      //api
          class BingInterface {
              interface BingService {
                  companion object {
                      val BASE_URL = "https://cn.bing.com/"
                  }
            
                  @GET("HPImageArchive.aspx?format=js")
                  fun getImageInfo(@Query("idx") index:Int, @Query("n") num:Int): Call<BingPicController.Images>
              }
          }
          
      //同步
          HttpCreator
               .setIsUseLoggingInterceptor(true)
               .setTimeOut(20L)
               .setBaseURL(BingInterface.BingService.BASE_URL)
               .create(BingInterface.BingService::class.java)
               .getImageInfo(-1,1)
               .execute()
               .body()
               
      //异步
          HttpCreator
              .setIsUseLoggingInterceptor(true)
              .setTimeOut(20L)
              .setBaseURL(BingInterface.BingService.BASE_URL)
              .create(BingInterface.BingService::class.java)
              .getImageInfo(-1,1).enqueue(object :Callback<Images>(){
                   override fun onFailure(call: Call<Images>,
                   t: Throwable) {
                      TODO("not implemented")  
                  }
             
                  override fun onResponse(call: Call<Images>, response: Response<Images>) {
                      TODO("not implemented")  
                  }
             
              })