国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

扔掉okhttp、httpClient,來試試這款輕量級HTTP客戶端神器?

共 5938字,需瀏覽 12分鐘

 ·

2021-01-03 19:49


作者 |?伍陸七

來源 |?https://juejin.cn/post/6898485806587969544

SpringBoot項目直接使用okhttp、httpClient或者RestTemplate發(fā)起HTTP請求,既繁瑣又不方便統(tǒng)一管理。因此,在這里推薦一個適用于SpringBoot項目的輕量級HTTP客戶端框架retrofit-spring-boot-starter,使用非常簡單方便,同時又提供諸多功能增強。目前項目已經(jīng)更新至2.2.2版本,并且會持續(xù)進行迭代優(yōu)化。

github項目地址:

https://github.com/LianjiaTech/retrofit-spring-boot-starter

gitee項目地址:

https://gitee.com/lianjiatech/retrofit-spring-boot-starter

前言

Retrofit是適用于AndroidJava且類型安全的HTTP客戶端,其最大的特性的是支持通過接口的方式發(fā)起HTTP請求。而spring-boot是使用最廣泛的Java開發(fā)框架,但是Retrofit官方?jīng)]有支持與spring-boot框架快速整合,因此我們開發(fā)了retrofit-spring-boot-starter

retrofit-spring-boot-starter實現(xiàn)了Retrofitspring-boot框架快速整合,并且支持了諸多功能增強,極大簡化開發(fā)。

?項目持續(xù)優(yōu)化迭代,歡迎大家提ISSUE和PR!麻煩大家能給一顆star?,您的star是我們持續(xù)更新的動力!

功能特性

  • 自定義注入OkHttpClient
  • 注解式攔截器
  • 連接池管理
  • 日志打印
  • 請求重試
  • 錯誤解碼器
  • 全局?jǐn)r截器
  • 熔斷降級
  • 微服務(wù)之間的HTTP調(diào)用
  • 調(diào)用適配器
  • 數(shù)據(jù)轉(zhuǎn)換器

快速使用

引入依賴

<dependency>
????<groupId>com.github.lianjiatechgroupId>
????<artifactId>retrofit-spring-boot-starterartifactId>
????<version>2.2.2version>
dependency>
復(fù)制代碼

定義http接口

接口必須使用@RetrofitClient注解標(biāo)記!http相關(guān)注解可參考官方文檔:https://square.github.io/retrofit/。

@RetrofitClient(baseUrl?=?"${test.baseUrl}")
public?interface?HttpApi?{

????@GET("person")
????Result?getPerson(@Query("id")?Long?id);
}
復(fù)制代碼

注入使用

將接口注入到其它Service中即可使用!

@Service
public?class?TestService?{

????@Autowired
????private?HttpApi?httpApi;

????public?void?test()?{
????????//?通過httpApi發(fā)起http請求
????}
}
復(fù)制代碼

HTTP請求相關(guān)注解

HTTP請求相關(guān)注解,全部使用了retrofit原生注解。詳細信息可參考官方文檔:https://square.github.io/retrofit/,以下是一個簡單說明。

注解分類支持的注解
請求方式@GET?@HEAD?@POST?@PUT?@DELETE?@OPTIONS
請求頭@Header?@HeaderMap?@Headers
Query參數(shù)@Query?@QueryMap?@QueryName
path參數(shù)@Path
form-encoded參數(shù)@Field?@FieldMap?@FormUrlEncoded
文件上傳@Multipart?@Part?@PartMap
url參數(shù)@Url

配置項說明

retrofit-spring-boot-starter支持了多個可配置的屬性,用來應(yīng)對不同的業(yè)務(wù)場景。您可以視情況進行修改,具體說明如下:

配置默認(rèn)值說明
enable-logtrue啟用日志打印
logging-interceptorDefaultLoggingInterceptor日志打印攔截器
pool
連接池配置
disable-void-return-typefalse禁用java.lang.Void返回類型
retry-interceptorDefaultRetryInterceptor請求重試攔截器
global-converter-factoriesJacksonConverterFactory全局轉(zhuǎn)換器工廠
global-call-adapter-factoriesBodyCallAdapterFactory,ResponseCallAdapterFactory全局調(diào)用適配器工廠
enable-degradefalse是否啟用熔斷降級
degrade-typesentinel熔斷降級實現(xiàn)方式(目前僅支持Sentinel)
resource-name-parserDefaultResourceNameParser熔斷資源名稱解析器,用于解析資源名稱

yml配置方式:

retrofit:
??enable-response-call-adapter:?true
??#?啟用日志打印
??enable-log:?true
??#?連接池配置
??pool:
????test1:
??????max-idle-connections:?3
??????keep-alive-second:?100
????test2:
??????max-idle-connections:?5
??????keep-alive-second:?50
??#?禁用void返回值類型
??disable-void-return-type:?false
??#?日志打印攔截器
??logging-interceptor:?com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor
??#?請求重試攔截器
??retry-interceptor:?com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor
??#?全局轉(zhuǎn)換器工廠
??global-converter-factories:
????-?retrofit2.converter.jackson.JacksonConverterFactory
??#?全局調(diào)用適配器工廠
??global-call-adapter-factories:
????-?com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory
????-?com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory
??#?是否啟用熔斷降級
??enable-degrade:?true
??#?熔斷降級實現(xiàn)方式
??degrade-type:?sentinel
??#?熔斷資源名稱解析器
??resource-name-parser:?com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser
復(fù)制代碼

高級功能

自定義注入OkHttpClient

通常情況下,通過@RetrofitClient注解屬性動態(tài)創(chuàng)建OkHttpClient對象能夠滿足大部分使用場景。但是在某些情況下,用戶可能需要自定義OkHttpClient,這個時候,可以在接口上定義返回類型是OkHttpClient.Builder的靜態(tài)方法來實現(xiàn)。代碼示例如下:

@RetrofitClient(baseUrl?=?"http://ke.com")
public?interface?HttpApi3?{

????@OkHttpClientBuilder
????static?OkHttpClient.Builder?okhttpClientBuilder()?{
????????return?new?OkHttpClient.Builder()
????????????????.connectTimeout(1,?TimeUnit.SECONDS)
????????????????.readTimeout(1,?TimeUnit.SECONDS)
????????????????.writeTimeout(1,?TimeUnit.SECONDS);

????}

????@GET
????Result?getPerson(@Url?String?url,?@Query("id")?Long?id);
}
復(fù)制代碼

方法必須使用@OkHttpClientBuilder注解標(biāo)記!

注解式攔截器

很多時候,我們希望某個接口下的某些http請求執(zhí)行統(tǒng)一的攔截處理邏輯。為了支持這個功能,retrofit-spring-boot-starter提供了注解式攔截器,做到了基于url路徑的匹配攔截。使用的步驟主要分為2步:

  1. 繼承BasePathMatchInterceptor編寫攔截處理器;
  2. 接口上使用@Intercept進行標(biāo)注。如需配置多個攔截器,在接口上標(biāo)注多個@Intercept注解即可!

下面以給指定請求的url后面拼接timestamp時間戳為例,介紹下如何使用注解式攔截器。

繼承BasePathMatchInterceptor編寫攔截處理器
@Component
public?class?TimeStampInterceptor?extends?BasePathMatchInterceptor?{

????@Override
????public?Response?doIntercept(Chain?chain)?throws?IOException?{
????????Request?request?=?chain.request();
????????HttpUrl?url?=?request.url();
????????long?timestamp?=?System.currentTimeMillis();
????????HttpUrl?newUrl?=?url.newBuilder()
????????????????.addQueryParameter("timestamp",?String.valueOf(timestamp))
????????????????.build();
????????Request?newRequest?=?request.newBuilder()
????????????????.url(newUrl)
????????????????.build();
????????return?chain.proceed(newRequest);
????}
}

復(fù)制代碼
接口上使用@Intercept進行標(biāo)注
@RetrofitClient(baseUrl?=?"${test.baseUrl}")
@Intercept(handler?=?TimeStampInterceptor.class,?include?=?{"/api/**"},?exclude?=?"/api/test/savePerson")
public?interface?HttpApi?{

????@GET("person")
????Result?getPerson(@Query("id")?Long?id);

????@POST("savePerson")
????Result?savePerson(@Body?Person?person);
}
復(fù)制代碼

上面的@Intercept配置表示:攔截HttpApi接口下/api/**路徑下(排除/api/test/savePerson)的請求,攔截處理器使用TimeStampInterceptor。

擴展注解式攔截器

有的時候,我們需要在攔截注解動態(tài)傳入一些參數(shù),然后再執(zhí)行攔截的時候需要使用這個參數(shù)。這種時候,我們可以擴展實現(xiàn)自定義攔截注解自定義攔截注解必須使用@InterceptMark標(biāo)記,并且注解中必須包括include()、exclude()、handler()屬性信息。使用的步驟主要分為3步:

  1. 自定義攔截注解
  2. 繼承BasePathMatchInterceptor編寫攔截處理器
  3. 接口上使用自定義攔截注解;

例如我們需要在請求頭里面動態(tài)加入accessKeyIdaccessKeySecret簽名信息才能正常發(fā)起http請求,這個時候可以自定義一個加簽攔截器注解@Sign來實現(xiàn)。下面以自定義@Sign攔截注解為例進行說明。

自定義@Sign注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@InterceptMark
public?@interface?Sign?{
????/**
?????*?密鑰key
?????*?支持占位符形式配置。
?????*
?????*?@return
?????*/

????String?accessKeyId();

????/**
?????*?密鑰
?????*?支持占位符形式配置。
?????*
?????*?@return
?????*/

????String?accessKeySecret();

????/**
?????*?攔截器匹配路徑
?????*
?????*?@return
?????*/

????String[]?include()?default?{"/**"};

????/**
?????*?攔截器排除匹配,排除指定路徑攔截
?????*
?????*?@return
?????*/

????String[]?exclude()?default?{};

????/**
?????*?處理該注解的攔截器類
?????*?優(yōu)先從spring容器獲取對應(yīng)的Bean,如果獲取不到,則使用反射創(chuàng)建一個!
?????*
?????*?@return
?????*/

????Class?handler()?default?SignInterceptor.class;
}
復(fù)制代碼

擴展自定義攔截注解有以下2點需要注意:

  1. 自定義攔截注解必須使用@InterceptMark標(biāo)記。
  2. 注解中必須包括include()、exclude()、handler()屬性信息。
實現(xiàn)SignInterceptor
@Component
public?class?SignInterceptor?extends?BasePathMatchInterceptor?{

????private?String?accessKeyId;

????private?String?accessKeySecret;

????public?void?setAccessKeyId(String?accessKeyId)?{
????????this.accessKeyId?=?accessKeyId;
????}

????public?void?setAccessKeySecret(String?accessKeySecret)?{
????????this.accessKeySecret?=?accessKeySecret;
????}

????@Override
????public?Response?doIntercept(Chain?chain)?throws?IOException?{
????????Request?request?=?chain.request();
????????Request?newReq?=?request.newBuilder()
????????????????.addHeader("accessKeyId",?accessKeyId)
????????????????.addHeader("accessKeySecret",?accessKeySecret)
????????????????.build();
????????return?chain.proceed(newReq);
????}
}
復(fù)制代碼

上述accessKeyIdaccessKeySecret字段值會依據(jù)@Sign注解的accessKeyId()accessKeySecret()值自動注入,如果@Sign指定的是占位符形式的字符串,則會取配置屬性值進行注入。另外,accessKeyIdaccessKeySecret字段必須提供setter方法。

接口上使用@Sign
@RetrofitClient(baseUrl?=?"${test.baseUrl}")
@Sign(accessKeyId?=?"${test.accessKeyId}",?accessKeySecret?=?"${test.accessKeySecret}",?exclude?=?{"/api/test/person"})
public?interface?HttpApi?{

????@GET("person")
????Result?getPerson(@Query("id")?Long?id);

????@POST("savePerson")
????Result?savePerson(@Body?Person?person);
}
復(fù)制代碼

這樣就能在指定url的請求上,自動加上簽名信息了。

連接池管理

默認(rèn)情況下,所有通過Retrofit發(fā)送的http請求都會使用max-idle-connections=5 keep-alive-second=300的默認(rèn)連接池。當(dāng)然,我們也可以在配置文件中配置多個自定義的連接池,然后通過@RetrofitClientpoolName屬性來指定使用。比如我們要讓某個接口下的請求全部使用poolName=test1的連接池,代碼實現(xiàn)如下:

  1. 配置連接池。

    retrofit:
    ????#?連接池配置
    ????pool:
    ????????test1:
    ????????max-idle-connections:?3
    ????????keep-alive-second:?100
    ????????test2:
    ????????max-idle-connections:?5
    ????????keep-alive-second:?50
    復(fù)制代碼
  2. 通過@RetrofitClientpoolName屬性來指定使用的連接池。

    @RetrofitClient(baseUrl?=?"${test.baseUrl}",?poolName="test1")
    public?interface?HttpApi?{

    ????@GET("person")
    ????Result?getPerson(@Query("id")?Long?id);
    }
    復(fù)制代碼

日志打印

很多情況下,我們希望將http請求日志記錄下來。通過retrofit.enableLog配置可以全局控制日志是否開啟。針對每個接口,可以通過@RetrofitClientenableLog控制是否開啟,通過logLevellogStrategy,可以指定每個接口的日志打印級別以及日志打印策略。retrofit-spring-boot-starter支持了5種日志打印級別(ERROR,?WARN,?INFO,?DEBUG,?TRACE),默認(rèn)INFO;支持了4種日志打印策略(NONE,?BASIC,?HEADERS,?BODY),默認(rèn)BASIC。4種日志打印策略含義如下:

  1. NONE:No logs.
  2. BASIC:Logs request and response lines.
  3. HEADERS:Logs request and response lines and their respective headers.
  4. BODY:Logs request and response lines and their respective headers and bodies (if present).

retrofit-spring-boot-starter默認(rèn)使用了DefaultLoggingInterceptor執(zhí)行真正的日志打印功能,其底層就是okhttp原生的HttpLoggingInterceptor。當(dāng)然,你也可以自定義實現(xiàn)自己的日志打印攔截器,只需要繼承BaseLoggingInterceptor(具體可以參考DefaultLoggingInterceptor的實現(xiàn)),然后在配置文件中進行相關(guān)配置即可。

retrofit:
??#?日志打印攔截器
??logging-interceptor:?com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor
復(fù)制代碼

請求重試

retrofit-spring-boot-starter支持請求重試功能,只需要在接口或者方法上加上@Retry注解即可。@Retry支持重試次數(shù)maxRetries、重試時間間隔intervalMs以及重試規(guī)則retryRules配置。重試規(guī)則支持三種配置:

  1. RESPONSE_STATUS_NOT_2XX:響應(yīng)狀態(tài)碼不是2xx時執(zhí)行重試;
  2. OCCUR_IO_EXCEPTION:發(fā)生IO異常時執(zhí)行重試;
  3. OCCUR_EXCEPTION:發(fā)生任意異常時執(zhí)行重試;

默認(rèn)響應(yīng)狀態(tài)碼不是2xx或者發(fā)生IO異常時自動進行重試。需要的話,你也可以繼承BaseRetryInterceptor實現(xiàn)自己的請求重試攔截器,然后將其配置上去。

retrofit:
??#?請求重試攔截器
??retry-interceptor:?com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor
復(fù)制代碼

錯誤解碼器

HTTP發(fā)生請求錯誤(包括發(fā)生異?;蛘唔憫?yīng)數(shù)據(jù)不符合預(yù)期)的時候,錯誤解碼器可將HTTP相關(guān)信息解碼到自定義異常中。你可以在@RetrofitClient注解的errorDecoder()指定當(dāng)前接口的錯誤解碼器,自定義錯誤解碼器需要實現(xiàn)ErrorDecoder接口:

/**
?*?錯誤解碼器。ErrorDecoder.
?*?當(dāng)請求發(fā)生異?;蛘呤盏綗o效響應(yīng)結(jié)果的時候,將HTTP相關(guān)信息解碼到異常中,無效響應(yīng)由業(yè)務(wù)自己判斷
?*
?*?When?an?exception?occurs?in?the?request?or?an?invalid?response?result?is?received,?the?HTTP?related?information?is?decoded?into?the?exception,
?*?and?the?invalid?response?is?determined?by?the?business?itself.
?*
?*?@author?陳添明
?*/

public?interface?ErrorDecoder?{

????/**
?????*?當(dāng)無效響應(yīng)的時候,將HTTP信息解碼到異常中,無效響應(yīng)由業(yè)務(wù)自行判斷。
?????*?When?the?response?is?invalid,?decode?the?HTTP?information?into?the?exception,?invalid?response?is?determined?by?business.
?????*
?????*?@param?request??request
?????*?@param?response?response
?????*?@return?If?it?returns?null,?the?processing?is?ignored?and?the?processing?continues?with?the?original?response.
?????*/

????default?RuntimeException?invalidRespDecode(Request?request,?Response?response)?{
????????if?(!response.isSuccessful())?{
????????????throw?RetrofitException.errorStatus(request,?response);
????????}
????????return?null;
????}


????/**
?????*?當(dāng)請求發(fā)生IO異常時,將HTTP信息解碼到異常中。
?????*?When?an?IO?exception?occurs?in?the?request,?the?HTTP?information?is?decoded?into?the?exception.
?????*
?????*?@param?request?request
?????*?@param?cause???IOException
?????*?@return?RuntimeException
?????*/

????default?RuntimeException?ioExceptionDecode(Request?request,?IOException?cause)?{
????????return?RetrofitException.errorExecuting(request,?cause);
????}

????/**
?????*?當(dāng)請求發(fā)生除IO異常之外的其它異常時,將HTTP信息解碼到異常中。
?????*?When?the?request?has?an?exception?other?than?the?IO?exception,?the?HTTP?information?is?decoded?into?the?exception.
?????*
?????*?@param?request?request
?????*?@param?cause???Exception
?????*?@return?RuntimeException
?????*/

????default?RuntimeException?exceptionDecode(Request?request,?Exception?cause)?{
????????return?RetrofitException.errorUnknown(request,?cause);
????}

}

復(fù)制代碼

全局?jǐn)r截器

全局應(yīng)用攔截器

如果我們需要對整個系統(tǒng)的的http請求執(zhí)行統(tǒng)一的攔截處理,可以自定義實現(xiàn)全局?jǐn)r截器BaseGlobalInterceptor, 并配置成spring容器中的bean!例如我們需要在整個系統(tǒng)發(fā)起的http請求,都帶上來源信息。

@Component
public?class?SourceInterceptor?extends?BaseGlobalInterceptor?{
????@Override
????public?Response?doIntercept(Chain?chain)?throws?IOException?{
????????Request?request?=?chain.request();
????????Request?newReq?=?request.newBuilder()
????????????????.addHeader("source",?"test")
????????????????.build();
????????return?chain.proceed(newReq);
????}
}
復(fù)制代碼

全局網(wǎng)絡(luò)攔截器

只需要實現(xiàn)NetworkInterceptor接口 并配置成spring容器中的bean就支持自動織入全局網(wǎng)絡(luò)攔截器。

熔斷降級

在分布式服務(wù)架構(gòu)中,對不穩(wěn)定的外部服務(wù)進行熔斷降級是保證服務(wù)高可用的重要措施之一。由于外部服務(wù)的穩(wěn)定性是不能保證的,當(dāng)外部服務(wù)不穩(wěn)定時,響應(yīng)時間會變長。相應(yīng)地,調(diào)用方的響應(yīng)時間也會變長,線程會產(chǎn)生堆積,最終可能耗盡調(diào)用方的線程池,導(dǎo)致整個服務(wù)不可用。因此我們需要對不穩(wěn)定的弱依賴服務(wù)調(diào)用進行熔斷降級,暫時切斷不穩(wěn)定調(diào)用,避免局部不穩(wěn)定導(dǎo)致整體服務(wù)雪崩。

retrofit-spring-boot-starter支持熔斷降級功能,底層基于Sentinel實現(xiàn)。具體來說,支持了熔斷資源自發(fā)現(xiàn)注解式降級規(guī)則配置。如需使用熔斷降級,只需要進行以下操作即可:

1. 開啟熔斷降級功能

默認(rèn)情況下,熔斷降級功能是關(guān)閉的,需要設(shè)置相應(yīng)的配置項來開啟熔斷降級功能

retrofit:
??#?是否啟用熔斷降級
??enable-degrade:?true
??#?熔斷降級實現(xiàn)方式(目前僅支持Sentinel)
??degrade-type:?sentinel
??#?資源名稱解析器
??resource-name-parser:?com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser
復(fù)制代碼

資源名稱解析器用于實現(xiàn)用戶自定義資源名稱,默認(rèn)配置是DefaultResourceNameParser,對應(yīng)的資源名稱格式為HTTP_OUT:GET:http://localhost:8080/api/degrade/test。用戶可以繼承BaseResourceNameParser類實現(xiàn)自己的資源名稱解析器。

另外,由于熔斷降級功能是可選的,因此啟用熔斷降級需要用戶自行引入Sentinel依賴

<dependency>
????<groupId>com.alibaba.cspgroupId>
????<artifactId>sentinel-coreartifactId>
????<version>1.6.3version>
dependency>
復(fù)制代碼
2. 配置降級規(guī)則(可選)

retrofit-spring-boot-starter支持注解式配置降級規(guī)則,通過@Degrade注解來配置降級規(guī)則。@Degrade注解可以配置在接口或者方法上,配置在方法上的優(yōu)先級更高。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,?ElementType.TYPE})
@Documented
public?@interface?Degrade?{

????/**
?????*?RT?threshold?or?exception?ratio?threshold?count.
?????*/

????double?count();

????/**
?????*?Degrade?recover?timeout?(in?seconds)?when?degradation?occurs.
?????*/

????int?timeWindow()?default?5;

????/**
?????*?Degrade?strategy?(0:?average?RT,?1:?exception?ratio).
?????*/

????DegradeStrategy?degradeStrategy()?default?DegradeStrategy.AVERAGE_RT;
}
復(fù)制代碼

如果應(yīng)用項目已支持通過配置中心配置降級規(guī)則,可忽略注解式配置方式。

3. @RetrofitClient設(shè)置fallback或者fallbackFactory (可選)

如果@RetrofitClient不設(shè)置fallback或者fallbackFactory,當(dāng)觸發(fā)熔斷時,會直接拋出RetrofitBlockException異常。用戶可以通過設(shè)置fallback或者fallbackFactory來定制熔斷時的方法返回值fallback類必須是當(dāng)前接口的實現(xiàn)類,fallbackFactory必須是FallbackFactory實現(xiàn)類,泛型參數(shù)類型為當(dāng)前接口類型。另外,fallbackfallbackFactory實例必須配置成Spring容器的Bean。

fallbackFactory相對于fallback,主要差別在于能夠感知每次熔斷的異常原因(cause)。參考示例如下:

@Slf4j
@Service
public?class?HttpDegradeFallback?implements?HttpDegradeApi?{

????@Override
????public?Result?test()?{
????????Result?fallback?=?new?Result<>();
????????fallback.setCode(100)
????????????????.setMsg("fallback")
????????????????.setBody(1000000);
????????return?fallback;
????}
}
復(fù)制代碼
@Slf4j
@Service
public?class?HttpDegradeFallbackFactory?implements?FallbackFactory<HttpDegradeApi>?{

????/**
?????*?Returns?an?instance?of?the?fallback?appropriate?for?the?given?cause
?????*
?????*?@param?cause?fallback?cause
?????*?@return?實現(xiàn)了retrofit接口的實例。an instance that implements the retrofit interface.
?????*/

????@Override
????public?HttpDegradeApi?create(Throwable?cause)?{
????????log.error("觸發(fā)熔斷了!?",?cause.getMessage(),?cause);
????????return?new?HttpDegradeApi()?{
????????????@Override
????????????public?Result?test()?{
????????????????Result?fallback?=?new?Result<>();
????????????????fallback.setCode(100)
????????????????????????.setMsg("fallback")
????????????????????????.setBody(1000000);
????????????????return?fallback;
????????????}
????}
}
復(fù)制代碼

微服務(wù)之間的HTTP調(diào)用

為了能夠使用微服務(wù)調(diào)用,需要進行如下配置:

配置ServiceInstanceChooserSpring容器Bean

用戶可以自行實現(xiàn)ServiceInstanceChooser接口,完成服務(wù)實例的選取邏輯,并將其配置成Spring容器的Bean。對于Spring Cloud應(yīng)用,retrofit-spring-boot-starter提供了SpringCloudServiceInstanceChooser實現(xiàn),用戶只需將其配置成SpringBean即可。

@Bean
@Autowired
public?ServiceInstanceChooser?serviceInstanceChooser(LoadBalancerClient?loadBalancerClient)?{
????return?new?SpringCloudServiceInstanceChooser(loadBalancerClient);
}
復(fù)制代碼
使用@RetrofitserviceIdpath屬性,可以實現(xiàn)微服務(wù)之間的HTTP調(diào)用
@RetrofitClient(serviceId?=?"${jy-helicarrier-api.serviceId}",?path?=?"/m/count",?errorDecoder?=?HelicarrierErrorDecoder.class)
@Retry
public?interface?ApiCountService?
{

}
復(fù)制代碼

調(diào)用適配器和數(shù)據(jù)轉(zhuǎn)碼器

調(diào)用適配器

Retrofit可以通過調(diào)用適配器CallAdapterFactoryCall對象適配成接口方法的返回值類型。retrofit-spring-boot-starter擴展2種CallAdapterFactory實現(xiàn):

  1. BodyCallAdapterFactory
    • 默認(rèn)啟用,可通過配置retrofit.enable-body-call-adapter=false關(guān)閉
    • 同步執(zhí)行http請求,將響應(yīng)體內(nèi)容適配成接口方法的返回值類型實例。
    • 除了Retrofit.Call、Retrofit.Response、java.util.concurrent.CompletableFuture之外,其它返回類型都可以使用該適配器。
  2. ResponseCallAdapterFactory
    • 默認(rèn)啟用,可通過配置retrofit.enable-response-call-adapter=false關(guān)閉
    • 同步執(zhí)行http請求,將響應(yīng)體內(nèi)容適配成Retrofit.Response返回。
    • 如果方法的返回值類型為Retrofit.Response,則可以使用該適配器。

Retrofit自動根據(jù)方法返回值類型選用對應(yīng)的CallAdapterFactory執(zhí)行適配處理!加上Retrofit默認(rèn)的CallAdapterFactory,可支持多種形式的方法返回值類型:

  • Call: 不執(zhí)行適配處理,直接返回Call對象
  • CompletableFuture: 將響應(yīng)體內(nèi)容適配成CompletableFuture對象返回
  • Void: 不關(guān)注返回類型可以使用Void。如果http狀態(tài)碼不是2xx,直接拋錯!
  • Response: 將響應(yīng)內(nèi)容適配成Response對象返回
  • 其他任意Java類型:將響應(yīng)體內(nèi)容適配成一個對應(yīng)的Java類型對象返回,如果http狀態(tài)碼不是2xx,直接拋錯!
????/**
?????*?Call
?????*?不執(zhí)行適配處理,直接返回Call對象
?????*?@param?id
?????*?@return
?????*/

????@GET("person")
????Call>?getPersonCall(@Query("id")?Long?id);

????/**
?????*??CompletableFuture
?????*??將響應(yīng)體內(nèi)容適配成CompletableFuture對象返回
?????*?@param?id
?????*?@return
?????*/

????@GET("person")
????CompletableFuture>?getPersonCompletableFuture(@Query("id")?Long?id);

????/**
?????*?Void
?????*?不關(guān)注返回類型可以使用Void。如果http狀態(tài)碼不是2xx,直接拋錯!
?????*?@param?id
?????*?@return
?????*/

????@GET("person")
????Void?getPersonVoid(@Query("id")?Long?id);

????/**
?????*??Response
?????*??將響應(yīng)內(nèi)容適配成Response對象返回
?????*?@param?id
?????*?@return
?????*/

????@GET("person")
????Response>?getPersonResponse(@Query("id")?Long?id);

????/**
?????*?其他任意Java類型
?????*?將響應(yīng)體內(nèi)容適配成一個對應(yīng)的Java類型對象返回,如果http狀態(tài)碼不是2xx,直接拋錯!
?????*?@param?id
?????*?@return
?????*/

????@GET("person")
????Result?getPerson(@Query("id")?Long?id);

復(fù)制代碼

我們也可以通過繼承CallAdapter.Factory擴展實現(xiàn)自己的CallAdapter

retrofit-spring-boot-starter支持通過retrofit.global-call-adapter-factories配置全局調(diào)用適配器工廠,工廠實例優(yōu)先從Spring容器獲取,如果沒有獲取到,則反射創(chuàng)建。默認(rèn)的全局調(diào)用適配器工廠是[BodyCallAdapterFactory, ResponseCallAdapterFactory]!

retrofit:
??#?全局調(diào)用適配器工廠
??global-call-adapter-factories:
????-?com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory
????-?com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory
復(fù)制代碼

針對每個Java接口,還可以通過@RetrofitClient注解的callAdapterFactories()指定當(dāng)前接口采用的CallAdapter.Factory,指定的工廠實例依然優(yōu)先從Spring容器獲取。

注意:如果CallAdapter.Factory沒有public的無參構(gòu)造器,請手動將其配置成Spring容器的Bean對象

數(shù)據(jù)轉(zhuǎn)碼器

Retrofit使用Converter@Body注解標(biāo)注的對象轉(zhuǎn)換成請求體,將響應(yīng)體數(shù)據(jù)轉(zhuǎn)換成一個Java對象,可以選用以下幾種Converter

  • Gson(https://github.com/google/gson): com.squareup.Retrofit:converter-gson
  • Jackson(https://github.com/FasterXML/jackson): com.squareup.Retrofit:converter-jackson
  • Moshi(https://github.com/square/moshi/): com.squareup.Retrofit:converter-moshi
  • Protobuf(https://developers.google.com/protocol-buffers/): com.squareup.Retrofit:converter-protobuf
  • Wire(https://github.com/square/wire): com.squareup.Retrofit:converter-wire
  • Simple XML(http://simple.sourceforge.net/): com.squareup.Retrofit:converter-simplexml
  • JAXB(https://docs.oracle.com/javase/tutorial/jaxb/intro/index.html): com.squareup.retrofit2:converter-jaxb

retrofit-spring-boot-starter支持通過retrofit.global-converter-factories配置全局?jǐn)?shù)據(jù)轉(zhuǎn)換器工廠,轉(zhuǎn)換器工廠實例優(yōu)先從Spring容器獲取,如果沒有獲取到,則反射創(chuàng)建。默認(rèn)的全局?jǐn)?shù)據(jù)轉(zhuǎn)換器工廠是retrofit2.converter.jackson.JacksonConverterFactory,你可以直接通過spring.jackson.*配置jackson序列化規(guī)則,配置可參考https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#howto-customize-the-jackson-objectmapper!

retrofit:
??#?全局轉(zhuǎn)換器工廠
??global-converter-factories:
????-?retrofit2.converter.jackson.JacksonConverterFactory
復(fù)制代碼

針對每個Java接口,還可以通過@RetrofitClient注解的converterFactories()指定當(dāng)前接口采用的Converter.Factory,指定的轉(zhuǎn)換器工廠實例依然優(yōu)先從Spring容器獲取。

注意:如果Converter.Factory沒有public的無參構(gòu)造器,請手動將其配置成Spring容器的Bean對象

總結(jié)

retrofit-spring-boot-starter一個適用于SpringBoot項目的輕量級HTTP客戶端框架,已在線上穩(wěn)定運行一年多,并且已經(jīng)有多個外部公司也接入使用。有興趣的朋友可以嘗試一下。

關(guān)注公眾號【Java技術(shù)江湖】后回復(fù)“PDF”即可領(lǐng)取200+頁的《Java工程師面試指南》

強烈推薦,幾乎涵蓋所有Java工程師必知必會的知識點,不管是復(fù)習(xí)還是面試,都很實用。



瀏覽 90
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點贊
評論
收藏
分享

手機掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 久操播放器| 爱爱综合| 国产人成视频免费观看| 亚洲黄色成人网站| ThePorn日本无码| 婷婷五月天成人| 91一级A片在线观看| 成人性爱福利视频| 99人妻视频| 豆花视频logo| 老婆被黑人杂交呻吟视频| 男女成人视频| 免费观看日韩无码视频| 日韩人妻无码一区二区三区七区| 伊人色五月| 欧美性爱小说网| 黄色视频a| 爱爱综合| 日韩欧美日韩| 日韩人妻电影| 欲色av| V天堂在线| 黄色视频在线网站| 粉嫩小泬粉嫩小泬在线| 国产www视频| 亚洲成人情趣大香蕉| 小草久久95| 97久久97欧美精品A片| 三级网站大全| 2022黄片| 精品人伦一区二区三区| 一级特黄毛片| 亚洲无码在线资源| 中字无码av| 99色逼| 成人无码www在线看免费| 亚洲av高清无码| 久草热视频| 无码在线高清| 首屈一指视频在线观看| 无码激情18激情视频| 思思热精品在线| 欧美人操逼一二区| 黄色视频网站在线| 黃色一级A一片人与| 亚洲色图成人网| 久久久成人网站| 另类老妇性BBwBBw图片| 国产女人与禽zOz0性| 久久九九视频| 国产综合亚洲精品一区二| i美女福利视频| 日韩免费av| 嫩草国产| 国产欧美一区二区三区四区| 婷婷国产AV| 蜜桃91精品入口| 久久精品一二三| 懂色av蜜臀av粉嫩av分| 在线一区视频| 2021狠狠操| 在线看V片| 亚洲AV在线看| 大香蕉av一区二区三区在线观看| 18禁免费网站| 亚洲人成在线观看| 性色网| 北条麻妃高清无码| 日本性爱无码| 久99视频| 高清无码在线不卡| 91精品电影| 91在线无码精品秘入口男同| 成人性爱视频在线播放| jizz免费在线观看| 屁屁影院CCYYCOM国产| 少妇高潮一区二区三区99| 蜜桃成人久久| 熟女视频一区二区| 欧美在线看片| 婷婷五月电影| 操人| 边吃奶边做爱| 天天想天天干| 久草视频在线资源| 日韩美女毛片| 男女操逼视频网站免费| 亚洲国产熟妇综合色专区| 澳门黄片| 六月婷| 91成人免费视频| 亚洲精品区| 91精品久久久久久| 高清无码毛片| 秋霞午夜成人无码精品| 国内老熟妇对白XXXXHD| 高清无码视频网站| 成人三级电影| 国产福利小视频| 欧美成人精品欧美一级乱黄| 日韩免费视频在线观看| 黄片在线视频| AV黄色| 久草视频免费在线观看| 另类一区| 成人三级片在线观看| 婷婷色图| 激情婷婷 | 综合天天| 久久综合伊人777777| 囯产精品一区二区三区线一牛影视1| 人人草在线观看| 91热久久| 午夜操逼网| 一道本无码一区| 成人免费毛片蓝莓| 国产毛片毛片毛片| 国产三级片在线免费观看| 操啊操| 蜜臀999| 成人乱妇无码AV在线| 悠悠色影院| 三级片在线看| 蜜桃AV| 91在线无码精品秘国产三年| 久久午夜无码鲁丝片午夜精品偷窥 | 北条麻妃视频在线观看| 亚洲色情网站| 欧美三级在线| 成人免费区一区二区三区| 丁香五月天在线播放| 你懂的久久| 婷婷欧美色图| 东北骚妇大战黑人视频| 97成人精品| 伊人成人在线视频观看| 无码人妻一区二区三区在线视频不卡| 成人免费一区| 97天天干| 亚洲午夜久久久久久久久红桃| 久久aaa| 无码视频观看| 国产精品久久久久毛片SUV| 欧美视频一区二区| 黄色A片网站| 天天干天天操天天射| 大香蕉国产视频| 欧美成人视频大全| 中国少妇| 午夜福利h| 黄色视频免费观看国产| 探花极品无套大学生| 亚洲黄色毛片| 密臀av在线| 99久久久国产精品无码| 一区亚洲| 欧美精品久久久久久久多人混战| 北条麻妃一区二区三区-免费免费高清观看 | 亚洲精品内射| 国产AV影视| 韩国色情中文字幕| 成人综合激情| 久久久久久久久黄色| 嫩BBB槡BBBB槡BBBB百度| 午夜天堂精品久久久| 欧美a片在线观看| 国产91在线亚洲| 91精品视频在线播放| 91狠狠综合久久| 无码免费视频| 性猛交╳XXX乱大交| 日本成人不卡| 91久久久久久久18| 中文字幕aV在线| 99在线精品视频免费观看20| 无码一二三区| 日韩人妻无码精品| 欧美视频在线免费| 丁香五月激情啪啪| 亚洲国产成人在线视频| 久久精品内射| 豆花视频成人网站入口免费观看 | 婷婷一区二区三区| 69av在线| 91麻豆精品国产91久久久久久久久| 久久久无码AV| 91精品国产成人做爰观看奶头 | 97国产成人| 香蕉一区二区| 97超碰在| 五月天婷婷影院| 91丨九色丨蝌蚪丨肥女| 日韩一区二区三区四区久久久精品有吗| 日韩一级性爱视频| 囯产精品一区二区三区线一牛影视1| 欧美亚洲色色网视频| 11孩岁女精品A片BBB| 黄一区二区| 一区视频免费观看| 亚洲精品不卡| 日毛片| 日韩高清国产一区在线| 骚视频网站| 69成人在线| 国产香蕉av| 国产欧美性爱| 91亚洲视频| 天天操天天操天天操天天| 手机AV在线观看| 国产91精品久久久天天| 久久草在线| 波多野结衣AV在线| 中文字幕69| 97人妻精品一区二区三区免| 人妻黄色视频| 欧美一级特黄A片免费看视频小说 东北嫖老熟女一区二区视频网站 国产丨熟女丨国产熟女视频 | 亚洲码成人| 丝瓜视频污APP| 久久久久久麻豆| 亚洲美女网站免费观看网址| 欧美伊人在线| 国产精品无码AV| 色色婷婷五月天| 天天干天天日蜜臀色欲av| 熟女熟妇人妻一区二区三区| 强伦轩人妻一区二区三区四区| 日本爱爱免费视频| 小泽玛利亚一区二区免费| 小早川怜子精品一区二区| 午夜天堂在线| 亚洲精品久久久久久久久久久| 国产91无码精品秘入口新欢| 成人免费区一区二区三区| 揉BBB搡BBB搡BBB| 欧美浮力影院| av无码网站| 国产嫩草久久久一二三久久免费观看| 欧美日韩人妻高清中文| 亚洲午夜精品久久久| 中文字幕AV在线观看| 色撸AⅤ| 亚洲中文无码av| 蜜桃精品视频在线观看| 综合天堂AV久久久久久久| 日韩AV性爱| 婷婷色中文网| 2025天天操| 天天日天天干天天射| 人妻丰满熟妇| 欧美日韩性爱网站| 婷婷在线观看视频| 精品无码久久| a片免费观看视频| 你懂的在线观看视频| 人人操超碰| 伊人热久久| 国产91精品久久久天天| 成人A片一级| 日操操| 亚韩av| 精品视频99| 欧美操B电影| 337p粉嫩噜噜噜| 欧美日韩v| 91精品久久人妻一区二区夜夜夜 | 澳门av| 在线观看黄a| 成功精品影院| 国产精品久久久久毛片SUV| 97超碰网| 午夜网页| A片久久久| 99色在线视频| 欧美日韩成人在线| 免费一区视频| 国产www在线观看| 91丨九色丨蝌蚪丨对白| 色哟哟无码| 日本高清视频网站网wwwwww | 亚洲综合免费观看高清完整版| 欧美在线观看网站18| 中文资源在线a中文| 国产精品久久久久久久久| 欧美性猛交ⅩXXX乱大交| 91狠狠| 男女做爱无码| 欧美性爱五月天| 久久成人综合网| 日韩久久人妻| 日韩高清无码免费| 久久精品免费电影| 亚洲操逼网站| 天天舔天天操| 伊人亚洲综合| 欧美亚洲日韩一区| 七十路の高齡熟妇无码| 人妻无码在线观看| 色婷婷在线无码精品秘人口传媒| 成人女人18女人毛片| 久激情内射婷内射蜜桃欧美一级| 一级片在线播放| 欧美888| 大香蕉亚洲| 日本黄色A片免费看| 欧美一二三区| 国产小视频在线看| 日本AV在线播放| 波多野结衣AV网站| 内射国产| 日韩欧美中文字幕视频| 麻豆国产一区二区三区四区| 最美人妖系列国产Ts涵涵| 麻豆激情| 欧美一级特黄AAAAAA片在线视频| 天天色天天爱| 无码人妻精品一区二区50| 久草久久| 欧美撸一撸| 久久成人电影院| A片地址| 久久噜| 丁香五月亭亭| 免费看成人A片无码照片88hⅤ| 综合激情五月婷婷| 日韩高清无码一区二区三区| 亚洲avwww| 99国产精品99久久久久久粉嫩 | 黄色网址在线免费观看| 东京亚洲无码| 丝袜美腿亚洲综合| 色五月婷婷小说| 欧美成人三区性价比| 夜夜操狠狠操| 久久亚洲AV| 日韩综合区| 国产无码高潮在线| 亚洲香蕉影院| 欧美老妇另类老屁XXX| 婷婷69| 日韩性爱在线| 亚洲无码性爱视频| 91大神久久| 在线18禁| 欧美操B在线| 日本三级中文字幕| 在线免费黄色网址| 91久久国产性奴调教| 精品久久免费一区二区三区| 日韩成人无码视频| 欧美日韩第一区| 91视频亚洲| 亚洲日韩欧美中在线| 丁香色综合人妻| 神马午夜秋霞不卡| 亚洲性图第一页| 97人妻一区二区三区| 欧美日韩亚洲另类| 国产有码视频| 色国产在线视频| 99久久精品国产毛片| 处破女初破全过免费看| 天天色伊人| 日韩欧美一| 在线不卡中文字幕| 亚洲精品视频无码| 日韩无码av电影| 九九免费视频| 国产精品一区二区不卡| 一级视频免费观看| 蜜臀久久99精品久久久久久婷婷| 亚洲高清视频在线观看| 日韩无码免费电影| 亚洲高清视频一区| 国产A片免费观看| 亚洲一区二区av| 国产特級黃色大片| 精品蜜桃秘一区二区三区在线播放| 性感成人在线| 一级二级三级无码| 久久人妻视频| 色婷婷一级A片AAA毛片| 国产欧美综合在线观看| 丁香五月天社区| 亚洲精品成人片在线观看精品字幕 | 第四色色综合| 人人色综合| 99久久伊人| 午夜福利手机在线| 成人国产精品在线看| 一本色道久久综合亚洲怎么玩| 在线看a片| 香蕉视频毛片| 成人免看一级a一片| 欧美午夜福利电影| 成人自拍视频在线| 成人毛片网| 日韩欧美国产精品| 亚洲无码理论片| 青青国产视频| 免费观看操逼| 在线观看中文字幕视频| 欧美一级婬片免费视频黄| 天天操比| 亚洲天堂2014| 草久在线视频| 久久精品五月天| 翔田千里高潮90分钟| 99re在线视频观看| 人人干超碰| 在线无码| 亚洲无码AV在线播放| 操碰在线观看| 人妻无码| 大香蕉网伊| 波多野结衣AV在线观看| 蜜桃一区二区中午字幕| 日韩无码人妻一区二区| 大香蕉在线视频网| 亚洲猛男操逼欧美国产视频 | 中文字幕天天干| 大肉大捧一进一出免费阅读| 亚洲无码成人电影| 国产91网| 天天射天天日天天干| 99热精品在线| 人妻丰满熟妇av无码区| 蜜臀av网| 尹人香蕉久久| 成人午夜视频在线观看| 成人做爰黄A片免费看| 国产人成视频免费观看| 亚洲精品蜜桃| 色噜噜狠狠一区二区三区牛牛影视| 精品AV国产| 日本日韩欧美| 深夜福利av| 四虎成人精品永久免费AV九九| 成人视频免费观看18| av片在线观看| 日韩精品无码AV| 奇米四色秒播| 精品在线免费视频| 国产日逼网站| 好看的中文字幕av| 日韩一级片在线观看| 91精品免费| 天天干,夜夜爽| 午夜精品久久久久久久久久久久| 亚洲精品中文字幕无码| 国产高清免费无码| 成人中文字幕无码| 波多野结衣高清无码| 91网站免费看| 婷婷福利导航| 另类视频区| 色老板网站| 国产日本在线| 麻豆AV片| 日韩性爱视频在线播放| 超碰日韩| 亚洲精品一级二级三级| 日本色区| 91国产爽黄| 婷婷性爱五月天| 中文资源在线观看| 伊人综合电影| 在线视频你懂得| 青草国产视频| 偷拍无码| 在线高清无码不卡| 亚洲黄色成人网站| 伊人影院在线视频| 天天舔天天干| 蜜桃无码视频小说网站| 色情欧美一级A片| av自拍| 国产视频激情| 人人上人人操| 久久久久久97电影院电影院无码| 欧美一级特黄A片免费看视频小说| 又黄又爽的网站| 91吴梦梦无码一区二区| www超碰在线| 午夜aaa| 青草无码视频| 日本V片| 日韩成人性爱网站| 日本高清视频网站网wwwwww| 波多野成人无码精品69| 欧美在线视频播放| 美国黄色A片| 日韩av中文字幕在线播放| 免费一区二区三区四区| 色哟哟国产| 亚l洲视频在线观看| wwwxx国产| 国际精品久久久| 天天操天天操天天操| 亚洲AV动漫| 91精品国产乱码香蕉黄瓜草莓| av天堂资源| 国产乱码精品一区二区三区的特点| 毛片二区| 四川少扫搡BBBBB搡B| 特黄特色大片BBBB| 蜜桃91在线| 日韩高清精品在线| 国产操逼片| 欧美性爱在线视频| A片在线观看免费| 精东av| 9l人人澡人人妻人人精品| 国产精品18在线| 91久久国产| 午夜福利10000| 一区二区三区观看| 亚洲国产精品精JIZZ老师| 亚洲A网站| 日本操逼网| 亚洲日本欧美| 男女啪啪| 亚洲无码精品一区二区三区| 免费A级黄片| 国产女人18毛片水18精品软件 | 天堂无码高清| 99久久婷婷国产综合精品青牛牛| 奇米久久| 爱搞搞就搞搞| 日本A级毛片| 亚洲av偷拍| 日韩欧美小电影| 骚BBBB槡BBB槡BBB| 久久水密桃| 中文字幕免费| 久免费视频| 日韩一级电影在线观看| 黄片无码免费观看| 99精品视频16在线免费观看 | 亚洲综合激情五月久久| 水蜜桃一区| 69国产精品| 一级性爽A√毛片| 久久夜夜操| 免费看黄色的网站| 99久久人妻精品免费二区| 日本黄色视频电影| 先锋AV资源| 日韩无码电影网站| 欧美性网站| 国产三级AV在线| 黄色片a片| 欧美熟妇高潮流白浆| 人人操91| 国产精品无码一区二区三| 亚色网址| 岛国AV在线| 欧美A视频| a网站在线观看| 再深点灬好爽灬轻点久久国产| 欧美sesese| 日本免费精品| 人妻HDHDHD96XXXX| 啪啪视频m3u8| 91丨豆花丨国产极品| 老鸭窝av免费入口在线观看| 一区二区三区免费观看| 成人精品免费视频| 91色婷婷综合久久中文字幕二区 | 91无码视频在线观看| 人妻无码视频| 日韩在线小视频| 97人妻精品一区二区三区| 丰满少妇在线观看网站| 91亚洲精品乱码久久久久久蜜桃| 97精品人妻一区二区三区在线| 91鲁| 一色综合| 午夜天堂在线| 成人H动漫精品一区二区无码| 欧美天天性| 大鸡巴视频在线| 一级黄色视频日逼片| 天天澡天天爽日日AV| 爱搞视频在线观看| 亚洲日韩视频在线观看| 亚洲精品高清无码| 欧美日韩操逼视频| 国产午夜无码视频在线观看| 国产精品福利小视频| 伊人蕉久| 欧美久久性爱| 一级二级三级视频| 在线视频你懂| 国产无码AV成在线| 久久亚洲精品视频| 羞羞av| 天天逼网| 无码在线视频播放| 成人777777| 亚洲三级精品| 久久嫩草精品| 欧美日韩精品一区二区三区| 久久久久国产一区二区三区四区 | 国产激情视频在线播放| 午夜福利久久| 十八禁无码网站在线观看| 一级Aa视频免费看| 免费的av网站| 怡春院AV| 精品无码三级在线观看视频 | 成人AV一区二区三区| 色爱av| 草逼视频网站| 学生妹内射| 综合色色婷婷| 日韩三级在线播放| 精品成人AV| 人人夜夜人人| 日韩中文字幕视频在线观看| 日韩少妇无码| 青草久久网| 亚洲天堂在线视频播放| 中文字幕免费无码| 国产亚洲无码激情| 久久永久免费| 日韩在线网址| 久久久久久久网| 激情综| 99国产精品久久久久久久成人 | 福利无码| 午夜亚洲福利| 久久大屌| 欧美高清无码在线观看| 26uuu亚洲| 国产精品视频网站| 五月天成人网址| 偷拍777| 在线天堂av| 操逼在线播放| 欧美成人三级| 无码视频网| h片免费在线观看| 久久久噜噜噜久久中文字幕色伊伊| 第一福利视频导航| 成人国产在线| 欧美激情一区二区三区| 五月网| 影音先锋久久| 97视频在线| 韩国精精品视频| 制服丝袜无码| 亚洲有码人妻| 午夜三级视频| 欧美成人免费精品| 影音先锋AV天堂| 亚洲成免费| 伊人大香蕉视频在线观看| 波多野59部无码喷潮| 在线免费看黄视频| 青在线视频| 国产高清视频在线播放| 亚洲春色一区二区三区| 人妻丰满熟妇av无码区| 特级毛片片A片AAAAAA| 在线免费看毛片| 免费性爱视频网站| 久久久999精品日韩一区二区| 99热这里有精品| 国产无套在线观看| 人人妻人人澡人人爽久久| 国产逼逼| 精品国产一级A片黄毛网站| 久久久久久久久久久久国产精品 | 丁香激情视频| 亚洲视频精选| 久久毛片基地| 一级片黄片| 青娱乐精品在线| 黄片小视频在线观看| 伊人77| 超碰少妇| 日韩性爱网| 欧美性爱在线观看| 青娱乐在线成人| 欧美肏逼网| 亚洲va欧美ⅴa在线| 无码专区在线播放| 欧美久久久久久久| 影音先锋女人av噜噜色| 蜜臀av一区二区| 国产在线观看黄色| 亚洲精品视频无码| av无码在线观看| 黄色大片久草| 国内无码精品| 国精品无码一区二区三区在线秋菊 | 无码三级在线播放| 婷婷五月天色综合| 日本AAAA片| 五月婷婷无码| 99自拍| 成人无码中文字幕| 亚洲色吧| 日韩aaa视频| 人人上人人操| 福利一区在线观看| 亚洲人妻在线播放| 国产亲子乱XXXXinin| 日本黄色视频在线播放| 亚洲女人被黑人巨大的原因| 久久嫩草精品久久久久精| 色五月视频在线| 国产精品一区二区在线播放| 少妇高潮在线| 亚洲av动漫| 欧美性爱一区二区三区| av女人天堂| 91日综合欧美| 五月天国产视频| 大地影视官网第三页入口| 亚洲成人AV电影| 青春草在线观看国产| 91日本| 波多野结衣av在线| 日韩一及| 日日爱av| 亚洲视频大全| 亚洲天堂在线观看免费| 亚洲日韩Av无码中文字幕美国 | 亚洲三级片在线观看| 九九热播精品| 一级一级a免一级a做免费线看内裤| 96久久| 国产麻豆精品成人毛片| 日韩午夜福利视频| 久久久久久久国产| 亚洲性爱手机版| 中文字幕无码Av在线| 青青草原成人在线视频| 北条麻妃无码一区二区| 91大鸡巴| 高清无码一区二区三区| 亚洲精品A片| 广州媚黑妇系列视频在线| 人人草在线观看| 一本色道久久综合无码欧美| 婷婷射| 日本黄色视频官网| 亚洲av资源在线观看| 久久黄色精品视频| 成人免费视频国产免费麻豆,| 国产成人AⅤ| 色就是色欧美成人网| 亚洲人人爱| 免费性片| 伊人久久中文字幕| 日韩欧美三级| 这里只有精品91| 久草视频2| 亚洲精品一二| 国产香蕉网| 欧美性爱视频网站| 我要操视频| 五月激情六月婷婷| 中文字幕av一区二区| 亚洲a视频| 周晓琳AV| 国产一级婬乱片免费| 围内精品久久久久久久久久‘变脸| 成人福利网| 日本a视频| 国产精品99久久免费黑人人妻| 91精品国产成人做爰观看奶头| 91成人国产| 欧美性爱中文字幕| 蜜桃av秘无码一区二区三| 999久久久精品| 亚洲成人视频在线免费观看| 欧美亚洲激情| 综合+++夜夜| 亚洲无遮挡| 亚洲在线第一页| 91久久久久久久| 黄片视频免费看| 西西444WWW无码视频软件功能介绍 | 免费在线观看内射| 成人在线欧美| 91国产爽黄| 免费观看久久久| 一区无码高清| 天堂在线www| 在线免费无码| 亚洲综合伊人无码| 污网站18禁| 影音先锋资源站| 人人草人人| 欧洲AV片| www九九九| 伊人久久网站| 一品国精和二品国精的文化意义| 精品三级网站| 久久无码高清| 内射免费视频| 国产精品一级A片| 亚洲视频大全| 国产乱国产乱300精品| 青草娱乐| 十八无码成人免费网站| 成年人免费电影| 天天拍夜夜操| 亚洲中文字幕在线观看免费 | 日韩人妻午夜| 中文字幕日本成人| 国产四区| 久久久久国产| 亚洲色婷婷在线| 国产精品大全| 国产97视频| 国产精品色色色| 免费一级大片| 91偷拍网| 日韩不卡免费| 青草无码| 亚洲成人天堂| 翔田千里与黑人50分钟| 亚洲成a人| 成人无码区免费| 99精品在线| 国产精品囯产三级囯产AV野外| 天天操天天操天天| h片在线播放| 日韩无码乱码| 蜜臀久久99精品久久久兰草影视| 黑人无码视频| 中文字幕H| 日韩高清无码片| 亚洲AV成人无码精在线| 久久三级片电影| 六月激情网| 一道本久久| 大香伊人国产| 亚洲成a| 午夜国产码网站码| 东京热网站在线观看| 在线观看免费黄色| 一区色| 激情开心站| 性爱视频免费| 久久青草视频| 日日夜夜综合| 国产无遮挡A片又黄又爽小直播| 亚洲AV日韩AV永久无码网站| 一级黄片免费| 久草手机视频| 熟女探花精选| 在线观看18s| 91av视频在线| 亚洲人成免费网站| 中文字幕一区二区三区在线观看| 国产激情精品| 99久久久久久久无码| 亚洲熟女av中文字幕| 久久久久久久久久久高清毛片一级| 成人中文字幕网站| 不卡不在线中文| 免费操逼网站| 97人人操人人| 七十路の高齡熟妇无码| 亚洲成人网站视频| 玖玖激情| 久久人妻中文字幕| 国产成人电影一区二区| 国内精品久久久久久久| 五月丁香在线| 一级AV在线| 五月在线| 成人黄网在线观看| AV黄页| 在线观看黄色片| 黄色视频在线观看| 91亚洲精品乱码久久久久久蜜桃 | 手机免费av| 2024无码| 奇米91| A区性愛社区| 综合网插菊花| 国产综合第一页| 操女人的网站| 亚洲视频成人| 最美孕交vivoestv另类| 欧美日韩亚洲一区二区| 成人黄片网站| 另类老妇奶性生BBwBBw偷拍| 蜜桃AV在线播放| 久久99高清视频| 激情伊人五月天| 黄片网站免费| 精品在线播放视频| 国产主播福利| 熟妇高潮一区二区高潮|