英語文書
改造用のスプリング ブート スターター。迅速な統合と機能強化をサポートします。
プロジェクトは引き続き最適化および反復されており、誰でも問題や PR を送信することができます。スターを付けてください。あなたのスターが継続的な更新のモチベーションになります。
Github プロジェクトのアドレス: https://github.com/LianjiaTech/retrofit-spring-boot-starter
gitee プロジェクトのアドレス: https://gitee.com/lianjiatech/retrofit-spring-boot-starter
サンプルデモ: https://github.com/ismart-yuxi/retrofit-spring-boot-demo
このプロジェクトのサンプルデモを作成してくれた
@ismart-yuxi
に感謝します。
< dependency >
< groupId >com.github.lianjiatech</ groupId >
< artifactId >retrofit-spring-boot-starter</ artifactId >
< version >3.1.3</ version >
</ dependency >
起動に失敗した場合は、依存関係の競合が発生している可能性が高く、関連する依存関係を導入または除外してください。
インターフェイスには@RetrofitClient
アノテーションを付ける必要があります。 HTTP 関連の情報については、公式ドキュメント「レトロフィット公式ドキュメント」を参照してください。
@ RetrofitClient ( baseUrl = "${test.baseUrl}" )
public interface UserService {
/**
* 根据id查询用户姓名
*/
@ POST ( "getName" )
String getName ( @ Query ( "id" ) Long id );
}
注:メソッド リクエストのパスは
/
で始まる必要があることに注意してください。Retrofit
の場合、baseUrl=http://localhost:8080/api/test/
でメソッド リクエスト パスがperson
の場合、メソッドの完全なリクエスト パスはhttp://localhost:8080/api/test/person
になります。メソッドのリクエスト パスが/person
場合、メソッドの完全なリクエスト パスはhttp://localhost:8080/person
になります。
インターフェースを他のサービスに挿入して使用してください。
@ Service
public class BusinessService {
@ Autowired
private UserService userService ;
public void doBusiness () {
// call userService
}
}
デフォルトでは、 SpringBoot
スキャンパスがRetrofitClient
登録に自動的に使用されます。 @RetrofitScan
構成クラスに追加して、スキャンパスを手動で指定することもできます。
HTTP
リクエストに関連するアノテーションはすべてRetrofit
ネイティブ アノテーションを使用します。簡単に説明します。
注釈の分類 | サポートされている注釈 |
---|---|
リクエスト方法 | @GET @HEAD @POST @PUT @DELETE @OPTIONS @HTTP |
リクエストヘッダー | @Header @HeaderMap @Headers |
クエリパラメータ | @Query @QueryMap @QueryName |
パスパラメータ | @Path |
フォームエンコードされたパラメータ | @Field @FieldMap @FormUrlEncoded |
リクエストボディ | @Body |
ファイルのアップロード | @Multipart @Part @PartMap |
URLパラメータ | @Url |
詳細については、公式ドキュメントを参照してください: レトロフィット公式ドキュメント
このコンポーネントは、さまざまなビジネス シナリオに対応するために複数の構成可能な属性をサポートしています。サポートされている具体的な構成属性とデフォルト値は次のとおりです。
注: アプリケーションは、変更する構成項目を構成するだけで済みます。
retrofit :
# 全局转换器工厂
global-converter-factories :
- com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory
- retrofit2.converter.jackson.JacksonConverterFactory
# 全局调用适配器工厂(组件扩展的调用适配器工厂已经内置,这里请勿重复配置)
global-call-adapter-factories :
# 全局日志打印配置
global-log :
# 启用日志打印
enable : true
# 全局日志打印级别
log-level : info
# 全局日志打印策略
log-strategy : basic
# 是否聚合打印请求日志
aggregate : true
# 全局重试配置
global-retry :
# 是否启用全局重试
enable : false
# 全局重试间隔时间
interval-ms : 100
# 全局最大重试次数
max-retries : 2
# 全局重试规则
retry-rules :
- response_status_not_2xx
- occur_io_exception
# 全局超时时间配置
global-timeout :
# 全局读取超时时间
read-timeout-ms : 10000
# 全局写入超时时间
write-timeout-ms : 10000
# 全局连接超时时间
connect-timeout-ms : 10000
# 全局完整调用超时时间
call-timeout-ms : 0
# 熔断降级配置
degrade :
# 熔断降级类型。默认none,表示不启用熔断降级
degrade-type : none
# 全局sentinel降级配置
global-sentinel-degrade :
# 是否开启
enable : false
# 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N)
count : 1000
# 熔断时长,单位为 s
time-window : 5
# 降级策略(0:平均响应时间;1:异常比例;2:异常数量)
grade : 0
# 全局resilience4j降级配置
global-resilience4j-degrade :
# 是否开启
enable : false
# 根据该名称从#{@link CircuitBreakerConfigRegistry}获取CircuitBreakerConfig,作为全局熔断配置
circuit-breaker-config-name : defaultCircuitBreakerConfig
# 自动设置PathMathInterceptor的scope为prototype
auto-set-prototype-scope-for-path-math-interceptor : true
OkHttpClient
のタイムアウトのみを変更する必要がある場合は、 @RetrofitClient
関連フィールドを使用して変更するか、グローバル タイムアウト構成を変更できます。
OkHttpClient
他の構成を変更する必要がある場合は、 OkHttpClient
カスタマイズすることで実行できます。手順は次のとおりです。
SourceOkHttpClientRegistrar
インターフェイスを実装し、 SourceOkHttpClientRegistry#register()
メソッドを呼び出してOkHttpClient
を登録します
@ Component
public class CustomOkHttpClientRegistrar implements SourceOkHttpClientRegistrar {
@ Override
public void register ( SourceOkHttpClientRegistry registry ) {
// 注册customOkHttpClient,超时时间设置为1s
registry . register ( "customOkHttpClient" , new OkHttpClient . Builder ()
. connectTimeout ( Duration . ofSeconds ( 1 ))
. writeTimeout ( Duration . ofSeconds ( 1 ))
. readTimeout ( Duration . ofSeconds ( 1 ))
. addInterceptor ( chain -> chain . proceed ( chain . request ()))
. build ());
}
}
@RetrofitClient.sourceOkHttpClient
を通じて現在のインターフェイスで使用されるOkHttpClient
指定します
@ RetrofitClient ( baseUrl = "${test.baseUrl}" , sourceOkHttpClient = "customOkHttpClient" )
public interface CustomOkHttpUserService {
/**
* 根据id查询用户信息
*/
@ GET ( "getUser" )
User getUser ( @ Query ( "id" ) Long id );
}
注: コンポーネントは、指定された
OkHttpClient
直接使用しませんが、OkHttpClient
に基づいて新しい OkHttpClient を作成します。
このコンポーネントは、URL パスの一致に基づいたインターセプトをサポートするアノテーション インターセプターを提供します。使用する手順は次のとおりです。
BasePathMatchInterceptor
の継承@Intercept
アノテーションを使用して、使用するインターセプターを指定します複数のインターセプターを使用する必要がある場合は、インターフェース上で複数の
@Intercept
アノテーションをマークするだけです。
BasePathMatchInterceptor
を継承してインターセプト プロセッサを作成する @ Component
public class PathMatchInterceptor extends BasePathMatchInterceptor {
@ Override
protected Response doIntercept ( Chain chain ) throws IOException {
Response response = chain . proceed ( chain . request ());
// response的Header加上path.match
return response . newBuilder (). header ( "path.match" , "true" ). build ();
}
}
デフォルトでは、コンポーネントはBasePathMatchInterceptor
のscope
prototype
に自動的に設定します。 この機能はretrofit.auto-set-prototype-scope-for-path-math-interceptor=false
によってオフにできます。閉じた後、 scope
をprototype
に手動で設定する必要があります。
@ Component
@ Scope ( "prototype" )
public class PathMatchInterceptor extends BasePathMatchInterceptor {
}
@Intercept
使用してインターフェイスにアノテーションを付けます @ RetrofitClient ( baseUrl = "${test.baseUrl}" )
@ Intercept ( handler = PathMatchInterceptor . class , include = { "/api/user/**" }, exclude = "/api/user/getUser" )
// @Intercept() 如果需要使用多个路径匹配拦截器,继续添加@Intercept即可
public interface InterceptorUserService {
/**
* 根据id查询用户姓名
*/
@ POST ( "getName" )
Response < String > getName ( @ Query ( "id" ) Long id );
/**
* 根据id查询用户信息
*/
@ GET ( "getUser" )
Response < User > getUser ( @ Query ( "id" ) Long id );
}
上記の@Intercept
設定は、 InterceptorUserService
インターフェイス ( /api/user/getUser
を除く) の/api/user/**
パスにあるリクエストをインターセプトし、インターセプト プロセッサはPathMatchInterceptor
を使用することを意味します。
場合によっては、「インターセプト アノテーション」でいくつかのパラメーターを動的に渡し、インターセプト時にこれらのパラメーターを使用する必要があります。 このとき、「カスタム インターセプト アノテーション」を使用できます。手順は次のとおりです。
@InterceptMark
マークを使用する必要があり、注釈にはinclude、exclude、handler
フィールドを含める必要があります。BasePathMatchInterceptor
を継承してインターセプト プロセッサを作成するたとえば、「HTTP リクエストを開始する前に、 accessKeyId
とaccessKeySecret
署名情報をリクエスト ヘッダーに動的に追加する」必要がある場合、これを実現するために@Sign
アノテーションをカスタマイズできます。
@Sign
アノテーション @ Retention ( RetentionPolicy . RUNTIME )
@ Target ( ElementType . TYPE )
@ Documented
@ InterceptMark
public @interface Sign {
String accessKeyId ();
String accessKeySecret ();
String [] include () default { "/**" };
String [] exclude () default {};
Class <? extends BasePathMatchInterceptor > handler () default SignInterceptor . class ;
}
使用されるインターセプターは、 @Sign
アノテーションで指定されたSignInterceptor
です。
SignInterceptor
の実装 @ Component
@ Setter
public class SignInterceptor extends BasePathMatchInterceptor {
private String accessKeyId ;
private String accessKeySecret ;
@ Override
public Response doIntercept ( Chain chain ) throws IOException {
Request request = chain . request ();
Request newReq = request . newBuilder ()
. addHeader ( "accessKeyId" , accessKeyId )
. addHeader ( "accessKeySecret" , accessKeySecret )
. build ();
Response response = chain . proceed ( newReq );
return response . newBuilder (). addHeader ( "accessKeyId" , accessKeyId )
. addHeader ( "accessKeySecret" , accessKeySecret ). build ();
}
}
注:
accessKeyId
フィールドとaccessKeySecret
フィールドはsetter
メソッドを提供する必要があります。
インターセプターのaccessKeyId
およびaccessKeySecret
フィールドの値は、 @Sign
アノテーションのaccessKeyId()
およびaccessKeySecret()
値に基づいて自動的に挿入されます。 @Sign
プレースホルダーの形式で文字列を指定する場合、構成属性値はインジェクションに使用されます。
@Sign
を使用する @ RetrofitClient ( baseUrl = "${test.baseUrl}" )
@ Sign ( accessKeyId = "${test.accessKeyId}" , accessKeySecret = "${test.accessKeySecret}" , include = "/api/user/getAll" )
public interface InterceptorUserService {
/**
* 查询所有用户信息
*/
@ GET ( "getAll" )
Response < List < User >> getAll ();
}
このコンポーネントは、グローバル ログ出力と宣言型ログ出力をサポートしています。
デフォルトでは、グローバル ログの印刷が有効になっており、デフォルトの構成は次のとおりです。
retrofit :
# 全局日志打印配置
global-log :
# 启用日志打印
enable : true
# 全局日志打印级别
log-level : info
# 全局日志打印策略
log-strategy : basic
# 是否聚合打印请求日志
aggregate : true
# 日志名称,默认为{@link LoggingInterceptor} 的全类名
logName : com.github.lianjiatech.retrofit.spring.boot.log.LoggingInterceptor
4 つのログ出力戦略の意味は次のとおりです。
NONE
: ログはありません。BASIC
: リクエスト行とレスポンス行をログに記録します。HEADERS
: リクエスト行と応答行、およびそれぞれのヘッダーをログに記録します。BODY
: リクエスト行と応答行、およびそれぞれのヘッダーと本文 (存在する場合) をログに記録します。 一部のリクエストのログのみを出力する必要がある場合は、関連するインターフェイスまたはメソッドで@Logging
アノテーションを使用できます。
ログの出力動作を変更する必要がある場合は、 LoggingInterceptor
継承し、 Spring bean
として構成できます。
コンポーネントのサポートは、グローバル再試行と宣言的再試行をサポートします。
グローバル再試行はデフォルトでオフになっており、デフォルトの構成項目は次のとおりです。
retrofit :
# 全局重试配置
global-retry :
# 是否启用全局重试
enable : false
# 全局重试间隔时间
interval-ms : 100
# 全局最大重试次数
max-retries : 2
# 全局重试规则
retry-rules :
- response_status_not_2xx
- occur_io_exception
再試行ルールは 3 つの構成をサポートしています。
RESPONSE_STATUS_NOT_2XX
: レスポンスステータスコードが2xx
以外の場合にリトライOCCUR_IO_EXCEPTION
: IO例外が発生したときに再試行しますOCCUR_EXCEPTION
: 例外が発生した場合に再試行します一部のリクエストのみを再試行する必要がある場合は、対応するインターフェイスまたはメソッドで@Retry
アノテーションを使用できます。
リクエストの再試行動作を変更する必要がある場合は、 RetryInterceptor
継承してSpring bean
として構成できます。
サーキット ブレーカーのダウングレードはデフォルトでオフになっており、現在はsentinel
とresilience4j
の実装をサポートしています。
retrofit :
# 熔断降级配置
degrade :
# 熔断降级类型。默认none,表示不启用熔断降级
degrade-type : sentinel
degrade-type=sentinel
を設定して有効にし、関連するインターフェイスまたはメソッドで@SentinelDegrade
アノテーションを宣言します。
Sentinel
依存関係を手動で導入することを忘れないでください。
< dependency >
< groupId >com.alibaba.csp</ groupId >
< artifactId >sentinel-core</ artifactId >
< version >1.6.3</ version >
</ dependency >
さらに、グローバルSentinel
サーキット ブレーカーのダウングレードもサポートされています。
retrofit :
# 熔断降级配置
degrade :
# 熔断降级类型。默认none,表示不启用熔断降级
degrade-type : sentinel
# 全局sentinel降级配置
global-sentinel-degrade :
# 是否开启
enable : true
# ...其他sentinel全局配置
これを有効にするには、 degrade-type=resilience4j
を構成します。次に、関連するインターフェイスまたはメソッドで@Resilience4jDegrade
を宣言します。
Resilience4j
依存関係を手動で導入することを忘れないでください。
< dependency >
< groupId >io.github.resilience4j</ groupId >
< artifactId >resilience4j-circuitbreaker</ artifactId >
< version >1.7.1</ version >
</ dependency >
グローバルな resilience4j サーキット ブレーカーのダウングレードは、次の構成を通じて有効にできます。
retrofit :
# 熔断降级配置
degrade :
# 熔断降级类型。默认none,表示不启用熔断降级
degrade-type : resilience4j
# 全局resilience4j降级配置
global-resilience4j-degrade :
# 是否开启
enable : true
# 根据该名称从#{@link CircuitBreakerConfigRegistry}获取CircuitBreakerConfig,作为全局熔断配置
circuit-breaker-config-name : defaultCircuitBreakerConfig
サーキットブレーカーの構成管理:
CircuitBreakerConfigRegistrar
インターフェイスを実装し、 CircuitBreakerConfig
を登録します。
@ Component
public class CustomCircuitBreakerConfigRegistrar implements CircuitBreakerConfigRegistrar {
@ Override
public void register ( CircuitBreakerConfigRegistry registry ) {
// 替换默认的CircuitBreakerConfig
registry . register ( Constants . DEFAULT_CIRCUIT_BREAKER_CONFIG , CircuitBreakerConfig . ofDefaults ());
// 注册其它的CircuitBreakerConfig
registry . register ( "testCircuitBreakerConfig" , CircuitBreakerConfig . custom ()
. slidingWindowType ( CircuitBreakerConfig . SlidingWindowType . TIME_BASED )
. failureRateThreshold ( 20 )
. minimumNumberOfCalls ( 5 )
. permittedNumberOfCallsInHalfOpenState ( 5 )
. build ());
}
}
CircuitBreakerConfig
circuitBreakerConfigName
によって指定されます。 retrofit.degrade.global-resilience4j-degrade.circuit-breaker-config-name
または@Resilience4jDegrade.circuitBreakerConfigName
を含めます
ユーザーが他のサーキット ブレーカーの劣化実装を使用する必要がある場合は、 BaseRetrofitDegrade
を継承し、 Spring Bean
設定します。
@RetrofitClient
fallback
またはfallbackFactory
設定していない場合、サーキット ブレーカーがトリガーされると、 RetrofitBlockException
直接スローされます。 ユーザーは、 fallback
またはfallbackFactory
を設定することで、融合が発生したときのメソッドの戻り値をカスタマイズできます。
注:
fallback
クラスは現在のインターフェイスの実装クラスである必要があり、fallbackFactory
FallbackFactory<T>
実装クラスである必要があり、ジェネリック パラメーターの型は現在のインターフェイスの型である必要があります。さらに、fallback
とfallbackFactory
インスタンスをSpring Bean
として構成する必要があります。
fallbackと比べて、fallbackFactory fallback
fallbackFactory
、各サーキットブレーカーの異常原因(原因)を検知できることです。参考例は以下の通りです。
@ Slf4j
@ Service
public class HttpDegradeFallback implements HttpDegradeApi {
@ Override
public Result < Integer > test () {
Result < Integer > fallback = new Result <>();
fallback . setCode ( 100 )
. setMsg ( "fallback" )
. setBody ( 1000000 );
return fallback ;
}
}
@ Slf4j
@ Service
public class HttpDegradeFallbackFactory implements FallbackFactory < HttpDegradeApi > {
@ Override
public HttpDegradeApi create ( Throwable cause ) {
log . error ( "触发熔断了! " , cause . getMessage (), cause );
return new HttpDegradeApi () {
@ Override
public Result < Integer > test () {
Result < Integer > fallback = new Result <>();
fallback . setCode ( 100 )
. setMsg ( "fallback" )
. setBody ( 1000000 );
return fallback ;
}
};
}
}
HTTP
要求エラー (例外や応答データが期待を満たさないことを含む) が発生すると、エラー デコーダーはHTTP
関連の情報をカスタム例外にデコードできます。 @RetrofitClient
の errorDecoder errorDecoder()
アノテーションで現在のインターフェースのエラー デコーダーを指定できます。カスタム エラー デコーダーはErrorDecoder
インターフェースを実装する必要があります。
ServiceInstanceChooser
の継承ユーザーは自分でServiceInstanceChooser
インターフェースを実装し、サービス インスタンスの選択ロジックを完成させ、それをSpring Bean
として構成できます。 Spring Cloud
アプリケーションの場合、次の実装を使用できます。
@ Service
public class SpringCloudServiceInstanceChooser implements ServiceInstanceChooser {
private LoadBalancerClient loadBalancerClient ;
@ Autowired
public SpringCloudServiceInstanceChooser ( LoadBalancerClient loadBalancerClient ) {
this . loadBalancerClient = loadBalancerClient ;
}
/**
* Chooses a ServiceInstance URI from the LoadBalancer for the specified service.
*
* @param serviceId The service ID to look up the LoadBalancer.
* @return Return the uri of ServiceInstance
*/
@ Override
public URI choose ( String serviceId ) {
ServiceInstance serviceInstance = loadBalancerClient . choose ( serviceId );
Assert . notNull ( serviceInstance , "can not found service instance! serviceId=" + serviceId );
return serviceInstance . getUri ();
}
}
serviceId
とpath
を指定します @ RetrofitClient ( serviceId = "user" , path = "/api/user" )
public interface ChooserOkHttpUserService {
/**
* 根据id查询用户信息
*/
@ GET ( "getUser" )
User getUser ( @ Query ( "id" ) Long id );
}
システム全体のHTTP
リクエストに対して統一的なインターセプト処理を行う必要がある場合は、グローバル インターセプターGlobalInterceptor
を実装し、 spring Bean
として構成できます。
@ Component
public class MyGlobalInterceptor implements GlobalInterceptor {
@ Override
public Response intercept ( Chain chain ) throws IOException {
Response response = chain . proceed ( chain . request ());
// response的Header加上global
return response . newBuilder (). header ( "global" , "true" ). build ();
}
}
NetworkInterceptor
インターフェースを実装し、 spring Bean
として構成します。
Retrofit
CallAdapterFactory
を通じてCall<T>
オブジェクトをインターフェイス メソッドの戻り値の型に適応させることができます。このコンポーネントは、いくつかのCallAdapterFactory
実装を拡張します。
BodyCallAdapterFactory
HTTP
リクエストを同期的に実行し、レスポンス本文の内容をメソッドの戻り値の型に適合させます。BodyCallAdapterFactory
最も低い優先順位で使用できます。ResponseCallAdapterFactory
HTTP
リクエストを同期的に実行し、レスポンス本文の内容をRetrofit.Response<T>
に適合させて返します。ResponseCallAdapterFactory
、メソッドの戻り値の型がRetrofit.Response<T>
の場合にのみ使用できます。CallAdapterFactory
Retrofit
メソッドの戻り値の型に基づいて、対応するCallAdapterFactory
選択して適応処理を実行します。現在サポートされている戻り値の型は次のとおりです。
String
: Response Body
String
に適応させて返します。Long
/ Integer
/ Boolean
/ Float
/ Double
): Response Body
上記の基本タイプに適合させます。Java
タイプ: Response Body
対応するJava
オブジェクトに適応させて返します。CompletableFuture<T>
: Response Body
CompletableFuture<T>
オブジェクトに適応させて返します。Void
: 戻り値の型を気にしない場合は、 Void
を使用できます。Response<T>
: Response
Response<T>
オブジェクトに適応させて返します。Call<T>
: アダプテーション処理を実行せず、 Call<T>
オブジェクトを直接返します。Mono<T>
: Project Reactor
リアクティブな戻り値の型Single<T>
: Rxjava
応答型戻り値の型 ( Rxjava2/Rxjava3
をサポート)Completable
: Rxjava
応答型戻り値、 HTTP
リクエストには応答本文がありません ( Rxjava2/Rxjava3
をサポート) CallAdapter
CallAdapter.Factory
を継承することで拡張できます。
このコンポーネントはretrofit.global-call-adapter-factories
設定を通じてグローバル呼び出しアダプター ファクトリをサポートします。
retrofit :
# 全局转换器工厂(组件扩展的`CallAdaptorFactory`工厂已经内置,这里请勿重复配置)
global-call-adapter-factories :
# ...
Java インターフェイスごとに、 @RetrofitClient.callAdapterFactories
を通じて現在のインターフェイスで使用されるCallAdapter.Factory
指定することもできます。
提案:
CallAdapter.Factory
Spring Bean
として構成する
Retrofit
Converter
使用して@Body
アノテーション付きオブジェクトをRequest Body
に変換し、 Response Body
Java
オブジェクトに変換します。次のConverter
から選択できます。
このコンポーネントはretrofit.global-converter-factories
によるグローバルConverter.Factory
の構成をサポートします。デフォルトは、 retrofit2.converter.jackson.JacksonConverterFactory
です。
Jackson
構成を変更する必要がある場合は、 JacksonConverterFactory
のbean
構成を自分で上書きするだけです。
retrofit :
# 全局转换器工厂
global-converter-factories :
- com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory
- retrofit2.converter.jackson.JacksonConverterFactory
Java
インターフェイスごとに、 @RetrofitClient.converterFactories
を通じて現在のインターフェイスで使用されるConverter.Factory
を指定することもできます。
提案:
Converter.Factory
Spring Bean
として構成します。
@RetrofitClient
、 @Retry
、 @Logging
、 @Resilience4jDegrade
などのアノテーションは、メタ アノテーション、継承、 @AliasFor
をサポートします。
@ Retention ( RetentionPolicy . RUNTIME )
@ Target ( ElementType . TYPE )
@ Documented
@ Inherited
@ RetrofitClient ( baseUrl = "${test.baseUrl}" )
@ Logging ( logLevel = LogLevel . WARN )
@ Retry ( intervalMs = 200 )
public @interface MyRetrofitClient {
@ AliasFor ( annotation = RetrofitClient . class , attribute = "converterFactories" )
Class <? extends Converter . Factory >[] converterFactories () default { GsonConverterFactory . class };
@ AliasFor ( annotation = Logging . class , attribute = "logStrategy" )
LogStrategy logStrategy () default LogStrategy . BODY ;
}
@ FormUrlEncoded
@ POST ( "token/verify" )
Object tokenVerify ( @ Field ( "source" ) String source , @ Field ( "signature" ) String signature , @ Field ( "token" ) String token );
@ FormUrlEncoded
@ POST ( "message" )
CompletableFuture < Object > sendMessage ( @ FieldMap Map < String , Object > param );
// 对文件名使用URLEncoder进行编码
public ResponseEntity importTerminology ( MultipartFile file ){
String fileName = URLEncoder . encode ( Objects . requireNonNull ( file . getOriginalFilename ()), "utf-8" );
okhttp3 . RequestBody requestBody = okhttp3 . RequestBody . create ( MediaType . parse ( "multipart/form-data" ), file . getBytes ());
MultipartBody . Part part = MultipartBody . Part . createFormData ( "file" , fileName , requestBody );
apiService . upload ( part );
return ok (). build ();
}
HTTP
アップロードインターフェース @ POST ( "upload" )
@ Multipart
Void upload ( @ Part MultipartBody . Part file );
HTTP
ダウンロードインターフェース @ RetrofitClient ( baseUrl = "https://img.ljcdn.com/hc-picture/" )
public interface DownloadApi {
@ GET ( "{fileKey}" )
Response < ResponseBody > download ( @ Path ( "fileKey" ) String fileKey );
}
HTTP
ダウンロードの使用法 @ SpringBootTest ( classes = { RetrofitBootApplication . class })
@ RunWith ( SpringRunner . class )
public class DownloadTest {
@ Autowired
DownloadApi downLoadApi ;
@ Test
public void download () throws Exception {
String fileKey = "6302d742-ebc8-4649-95cf-62ccf57a1add" ;
Response < ResponseBody > response = downLoadApi . download ( fileKey );
ResponseBody responseBody = response . body ();
// 二进制流
InputStream is = responseBody . byteStream ();
// 具体如何处理二进制流,由业务自行控制。这里以写入文件为例
File tempDirectory = new File ( "temp" );
if (! tempDirectory . exists ()) {
tempDirectory . mkdir ();
}
File file = new File ( tempDirectory , UUID . randomUUID (). toString ());
if (! file . exists ()) {
file . createNewFile ();
}
FileOutputStream fos = new FileOutputStream ( file );
byte [] b = new byte [ 1024 ];
int length ;
while (( length = is . read ( b )) > 0 ) {
fos . write ( b , 0 , length );
}
is . close ();
fos . close ();
}
}
動的 URL は@url
アノテーションを使用して実装できます。現時点では、 baseUrl
任意の有効な URL で構成できます。例: http://github.com/
。実行時、リクエストは@Url
アドレスに基づいてのみ開始されます。
注:
@url
メソッドパラメータの最初の位置に配置する必要があります。また、@GET
、@POST
およびその他のアノテーションはエンドポイント パスを定義する必要はありません。
@ GET
Map < String , Object > test3 ( @ Url String url , @ Query ( "name" ) String name );
DELETE
リクエストはリクエストボディを追加します @ HTTP ( method = "DELETE" , path = "/user/delete" , hasBody = true )
GET
リクエストに追加するokhttp3
自体は、 GET
リクエストボディの追加をサポートしていません。ソースコードは次のとおりです。
著者は具体的な理由を述べています。以下を参照してください。
ただし、これを本当に行う必要がある場合は、 @HTTP(method = "get", path = "/user/get", hasBody = true)
使用し、小文字のget
を使用して上記の制限を回避できます。
ご質問がある場合は、問題を提起するか、QQ グループに参加してフィードバックを求めてください。
グループ番号: 806714302