Englisches Dokument
Spring-Boot-Starter für die Nachrüstung, der eine schnelle Integration und Funktionserweiterung unterstützt .
Das Projekt wird weiterhin optimiert und iteriert, und jeder ist willkommen, ISSUEs und PRs einzureichen! Bitte geben Sie uns einen Stern. Ihr Stern ist unsere Motivation für kontinuierliche Updates!
Github-Projektadresse: https://github.com/LianjiaTech/retrofit-spring-boot-starter
Gitee-Projektadresse: https://gitee.com/lianjiatech/retrofit-spring-boot-starter
Beispieldemo: https://github.com/ismart-yuxi/retrofit-spring-boot-demo
Vielen Dank an
@ismart-yuxi
für das Schreiben der Beispieldemo für dieses Projekt
< dependency >
< groupId >com.github.lianjiatech</ groupId >
< artifactId >retrofit-spring-boot-starter</ artifactId >
< version >3.1.3</ version >
</ dependency >
Wenn der Start fehlschlägt, liegt mit hoher Wahrscheinlichkeit ein Abhängigkeitskonflikt vor. Bitte führen Sie verwandte Abhängigkeiten ein oder schließen Sie sie aus .
Die Schnittstelle muss mit @RetrofitClient
gekennzeichnet sein ! Informationen zu HTTP finden Sie in der offiziellen Dokumentation: Offizielle Dokumentation zur Nachrüstung.
@ RetrofitClient ( baseUrl = "${test.baseUrl}" )
public interface UserService {
/**
* 根据id查询用户姓名
*/
@ POST ( "getName" )
String getName ( @ Query ( "id" ) Long id );
}
Hinweis: Methodenanforderungspfade sollten mit
/
mit Vorsicht beginnen . Wenn fürRetrofit
baseUrl=http://localhost:8080/api/test/
und der Methodenanforderungspfadperson
ist, lautet der vollständige Anforderungspfad der Methode:http://localhost:8080/api/test/person
. Wenn der Methodenanforderungspfad/person
ist, lautet der vollständige Anforderungspfad der Methode:http://localhost:8080/person
.
Integrieren Sie die Schnittstelle in andere Dienste und nutzen Sie sie!
@ Service
public class BusinessService {
@ Autowired
private UserService userService ;
public void doBusiness () {
// call userService
}
}
Standardmäßig wird der SpringBoot
Scanpfad automatisch für RetrofitClient
-Registrierung verwendet . Sie können der Konfigurationsklasse auch @RetrofitScan
hinzufügen, um den Scanpfad manuell anzugeben.
Anmerkungen im Zusammenhang mit HTTP
-Anfragen verwenden alle Retrofit
native Anmerkungen. Das Folgende ist eine einfache Erklärung:
Anmerkungsklassifizierung | Unterstützte Anmerkungen |
---|---|
Anfragemethode | @GET @HEAD @POST @PUT @DELETE @OPTIONS @HTTP |
Anforderungsheader | @Header @HeaderMap @Headers |
Abfrageparameter | @Query @QueryMap @QueryName |
Pfadparameter | @Path |
formcodierte Parameter | @Field @FieldMap @FormUrlEncoded |
Anforderungstext | @Body |
Datei-Upload | @Multipart @Part @PartMap |
URL-Parameter | @Url |
Detaillierte Informationen finden Sie in der offiziellen Dokumentation: Offizielle Dokumentation zur Nachrüstung
Die Komponente unterstützt mehrere konfigurierbare Attribute, um verschiedene Geschäftsszenarien zu bewältigen. Die spezifischen unterstützten Konfigurationsattribute und Standardwerte sind wie folgt:
Hinweis: Die Anwendung muss nur die zu ändernden Konfigurationselemente konfigurieren !
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
Wenn Sie nur den Timeout-Zeitraum von OkHttpClient
ändern müssen, können Sie ihn über die zugehörigen Felder @RetrofitClient
ändern oder die globale Timeout-Konfiguration ändern.
Wenn Sie andere Konfigurationen OkHttpClient
ändern müssen, können Sie dies tun, indem Sie OkHttpClient
anpassen. Die Schritte sind wie folgt:
Implementieren Sie die Schnittstelle SourceOkHttpClientRegistrar
und rufen Sie SourceOkHttpClientRegistry#register()
auf, um OkHttpClient
zu registrieren
@ 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 ());
}
}
Geben Sie über @RetrofitClient.sourceOkHttpClient
OkHttpClient
an, der von der aktuellen Schnittstelle verwendet werden soll
@ RetrofitClient ( baseUrl = "${test.baseUrl}" , sourceOkHttpClient = "customOkHttpClient" )
public interface CustomOkHttpUserService {
/**
* 根据id查询用户信息
*/
@ GET ( "getUser" )
User getUser ( @ Query ( "id" ) Long id );
}
Hinweis: Die Komponente verwendet den angegebenen
OkHttpClient
nicht direkt, sondern erstellt einen neuen basierend aufOkHttpClient
.
Die Komponente stellt einen Annotations-Interceptor bereit, der das Abfangen basierend auf dem URL-Pfadabgleich unterstützt. Die zu verwendenden Schritte sind wie folgt:
BasePathMatchInterceptor
erben@Intercept
um den zu verwendenden Interceptor anzugebenWenn Sie mehrere Interceptoren verwenden müssen, markieren Sie einfach mehrere
@Intercept
-Annotationen auf der Schnittstelle.
BasePathMatchInterceptor
, um einen Abfangprozessor zu schreiben @ 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 ();
}
}
Standardmäßig legt die Komponente scope
von BasePathMatchInterceptor
automatisch auf prototype
fest . Diese Funktion kann über retrofit.auto-set-prototype-scope-for-path-math-interceptor=false
deaktiviert werden. Nach dem Schließen müssen Sie scope
manuell auf prototype
setzen.
@ Component
@ Scope ( "prototype" )
public class PathMatchInterceptor extends BasePathMatchInterceptor {
}
@Intercept
, um die Schnittstelle mit Anmerkungen zu versehen @ 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 );
}
Die obige @Intercept
Konfiguration bedeutet: Anforderungen unter dem Pfad /api/user/**
unter der Schnittstelle InterceptorUserService
abfangen (ausgenommen /api/user/getUser
), und der Abfangprozessor verwendet PathMatchInterceptor
.
Manchmal müssen wir einige Parameter dynamisch in der „Abfanganmerkung“ übergeben und diese Parameter dann beim Abfangen verwenden. Zu diesem Zeitpunkt können wir „benutzerdefinierte Abfanganmerkungen“ verwenden. Die Schritte sind wie folgt:
@InterceptMark
Markierung verwendet werden und die Annotation muss include、exclude、handler
enthalten.BasePathMatchInterceptor
, um einen Abfangprozessor zu schreiben Beispielsweise müssen wir „die Signaturinformationen accessKeyId
und accessKeySecret
dynamisch zum Anforderungsheader hinzufügen, bevor wir eine HTTP-Anfrage initiieren. In diesem Fall können wir @Sign
-Annotation anpassen, um dies zu erreichen.
@Sign
Anmerkung @ 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 ;
}
Der verwendete Interceptor ist der in der @Sign
-Annotation angegebene 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 ();
}
}
Hinweis: Die Felder
accessKeyId
undaccessKeySecret
müssensetter
-Methoden bereitstellen.
accessKeyId
und accessKeySecret
des Interceptors werden @Sign
basierend auf accessKeyId()
und accessKeySecret()
der Annotation @Sign
eingefügt Der Wert des Konfigurationsattributs wird für die Injektion verwendet.
@Sign
auf der Schnittstelle @ RetrofitClient ( baseUrl = "${test.baseUrl}" )
@ Sign ( accessKeyId = "${test.accessKeyId}" , accessKeySecret = "${test.accessKeySecret}" , include = "/api/user/getAll" )
public interface InterceptorUserService {
/**
* 查询所有用户信息
*/
@ GET ( "getAll" )
Response < List < User >> getAll ();
}
Die Komponente unterstützt den globalen Protokolldruck und den deklarativen Protokolldruck.
Standardmäßig ist der globale Protokolldruck aktiviert und die Standardkonfiguration lautet wie folgt:
retrofit :
# 全局日志打印配置
global-log :
# 启用日志打印
enable : true
# 全局日志打印级别
log-level : info
# 全局日志打印策略
log-strategy : basic
# 是否聚合打印请求日志
aggregate : true
# 日志名称,默认为{@link LoggingInterceptor} 的全类名
logName : com.github.lianjiatech.retrofit.spring.boot.log.LoggingInterceptor
Die vier Protokolldruckstrategien haben folgende Bedeutung:
NONE
: Keine Protokolle.BASIC
: Protokolliert Anforderungs- und Antwortzeilen.HEADERS
: Protokolliert Anforderungs- und Antwortzeilen und ihre jeweiligen Header.BODY
: Protokolliert Anforderungs- und Antwortzeilen sowie ihre jeweiligen Header und Bodys (falls vorhanden). Wenn Sie nur für einige Anforderungen Protokolle drucken müssen, können Sie die Annotation @Logging
für die entsprechende Schnittstelle oder Methode verwenden.
Wenn Sie das Protokolldruckverhalten ändern müssen, können Sie LoggingInterceptor
erben und als Spring bean
konfigurieren.
Die Komponentenunterstützung unterstützt globale und deklarative Wiederholungsversuche.
Die globale Wiederholung ist standardmäßig deaktiviert und die Standardkonfigurationselemente lauten wie folgt:
retrofit :
# 全局重试配置
global-retry :
# 是否启用全局重试
enable : false
# 全局重试间隔时间
interval-ms : 100
# 全局最大重试次数
max-retries : 2
# 全局重试规则
retry-rules :
- response_status_not_2xx
- occur_io_exception
Wiederholungsregeln unterstützen drei Konfigurationen:
RESPONSE_STATUS_NOT_2XX
: Wiederholen Sie den Vorgang, wenn der Antwortstatuscode nicht 2xx
istOCCUR_IO_EXCEPTION
: Wiederholung durchführen, wenn eine E/A-Ausnahme auftrittOCCUR_EXCEPTION
: Wiederholen Sie den Vorgang, wenn eine Ausnahme auftritt Wenn nur einige Anfragen wiederholt werden müssen, können Sie die Annotation @Retry
für die entsprechende Schnittstelle oder Methode verwenden.
Wenn Sie das Verhalten bei Anforderungswiederholungen ändern müssen, können Sie RetryInterceptor
erben und als Spring bean
konfigurieren.
Das Downgrade des Leistungsschalters ist standardmäßig deaktiviert und unterstützt derzeit sentinel
und resilience4j
-Implementierungen.
retrofit :
# 熔断降级配置
degrade :
# 熔断降级类型。默认none,表示不启用熔断降级
degrade-type : sentinel
Konfigurieren Sie degrade-type=sentinel
, um es zu aktivieren, und deklarieren Sie dann die Annotation @SentinelDegrade
für die entsprechende Schnittstelle oder Methode.
Denken Sie daran, Sentinel
Abhängigkeiten manuell einzuführen:
< dependency >
< groupId >com.alibaba.csp</ groupId >
< artifactId >sentinel-core</ artifactId >
< version >1.6.3</ version >
</ dependency >
Darüber hinaus wird auch das globale Downgrade Sentinel
Leistungsschaltern unterstützt:
retrofit :
# 熔断降级配置
degrade :
# 熔断降级类型。默认none,表示不启用熔断降级
degrade-type : sentinel
# 全局sentinel降级配置
global-sentinel-degrade :
# 是否开启
enable : true
# ...其他sentinel全局配置
Konfigurieren Sie degrade-type=resilience4j
um es zu aktivieren. Dann deklarieren Sie @Resilience4jDegrade
für die entsprechende Schnittstelle oder Methode.
Denken Sie daran, Resilience4j
Abhängigkeit manuell einzuführen:
< dependency >
< groupId >io.github.resilience4j</ groupId >
< artifactId >resilience4j-circuitbreaker</ artifactId >
< version >1.7.1</ version >
</ dependency >
Das globale Downgrade des Leistungsschalters resilience4j kann durch die folgende Konfiguration aktiviert werden:
retrofit :
# 熔断降级配置
degrade :
# 熔断降级类型。默认none,表示不启用熔断降级
degrade-type : resilience4j
# 全局resilience4j降级配置
global-resilience4j-degrade :
# 是否开启
enable : true
# 根据该名称从#{@link CircuitBreakerConfigRegistry}获取CircuitBreakerConfig,作为全局熔断配置
circuit-breaker-config-name : defaultCircuitBreakerConfig
Verwaltung der Leistungsschalterkonfiguration:
Implementieren Sie die Schnittstelle CircuitBreakerConfigRegistrar
und registrieren Sie 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
wird durch circuitBreakerConfigName
angegeben. Fügen Sie retrofit.degrade.global-resilience4j-degrade.circuit-breaker-config-name
oder @Resilience4jDegrade.circuitBreakerConfigName
hinzu
Wenn der Benutzer eine andere Implementierung der Leistungsschalterverschlechterung verwenden muss, erben Sie BaseRetrofitDegrade
und konfigurieren Sie es Spring Bean
.
Wenn @RetrofitClient
weder fallback
noch fallbackFactory
festlegt, wird beim Auslösen des Leistungsschalters direkt RetrofitBlockException
ausgelöst. Benutzer können den Rückgabewert der Methode anpassen, wenn eine Fusion erfolgt, indem sie fallback
oder fallbackFactory
festlegen.
Hinweis: Die
fallback
-Klasse muss die Implementierungsklasse der aktuellen Schnittstelle sein,fallbackFactory
mussFallbackFactory<T>
sein und der generische Parametertyp muss der aktuelle Schnittstellentyp sein. Darüber hinaus müssenfallback
undfallbackFactory
Instanzen alsSpring Bean
konfiguriert werden.
Im Vergleich zum fallbackFactory
fallback
darin, dass die abnormale Ursache (Ursache) jedes Leistungsschalters erkannt werden kann. Das Referenzbeispiel lautet wie folgt:
@ 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 ;
}
};
}
}
Wenn HTTP
Anforderungsfehler auftritt (einschließlich einer Ausnahme oder die Antwortdaten nicht den Erwartungen entsprechen), kann der Fehlerdecoder HTTP
bezogene Informationen in eine benutzerdefinierte Ausnahme dekodieren. Sie können den Fehlerdecoder der aktuellen Schnittstelle in der Annotation errorDecoder errorDecoder()
von @RetrofitClient
angeben. Ein benutzerdefinierter Fehlerdecoder muss die Schnittstelle ErrorDecoder
implementieren:
ServiceInstanceChooser
erben Benutzer können die ServiceInstanceChooser
-Schnittstelle selbst implementieren, die Logik zur Auswahl der Dienstinstanz vervollständigen und sie als Spring Bean
konfigurieren. Für Spring Cloud
Anwendungen kann die folgende Implementierung verwendet werden.
@ 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
und path
an @ RetrofitClient ( serviceId = "user" , path = "/api/user" )
public interface ChooserOkHttpUserService {
/**
* 根据id查询用户信息
*/
@ GET ( "getUser" )
User getUser ( @ Query ( "id" ) Long id );
}
Wenn wir eine einheitliche Abfangverarbeitung für HTTP
Anfragen des gesamten Systems durchführen müssen, können wir den globalen Interceptor GlobalInterceptor
implementieren und ihn als spring Bean
konfigurieren.
@ 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 ();
}
}
Implementieren Sie die NetworkInterceptor
Schnittstelle und konfigurieren Sie sie als spring Bean
.
Retrofit
kann das Call<T>
-Objekt über CallAdapterFactory
an den Rückgabewerttyp der Schnittstellenmethode anpassen. Die Komponente erweitert einige CallAdapterFactory
Implementierungen:
BodyCallAdapterFactory
HTTP
Anfragen synchron aus und passen Sie den Inhalt des Antworttexts an den Rückgabewerttyp der Methode an.BodyCallAdapterFactory
mit der niedrigsten Priorität verwenden.ResponseCallAdapterFactory
HTTP
Anfrage synchron aus, passen Sie den Inhalt des Antworttexts an Retrofit.Response<T>
an und geben Sie ihn zurück.ResponseCallAdapterFactory
kann nur verwendet werden, wenn der Rückgabewerttyp der Methode Retrofit.Response<T>
ist.CallAdapterFactory
im Zusammenhang mit der reaktiven Programmierung Retrofit
wählt die entsprechende CallAdapterFactory
aus, um die Anpassungsverarbeitung basierend auf dem Rückgabewerttyp der Methode durchzuführen . Die derzeit unterstützten Rückgabewerttypen sind wie folgt:
String
: Passen Sie Response Body
an String
an und geben Sie ihn zurück.Long
/ Integer
/ Boolean
/ Float
/ Double
): Passen Sie Response Body
an die oben genannten Grundtypen anJava
Typ: Passen Sie Response Body
an das entsprechende Java
-Objekt an und geben Sie es zurückCompletableFuture<T>
: Passen Sie Response Body
an CompletableFuture<T>
-Objekt an und geben Sie es zurückVoid
: Sie können Void
verwenden, wenn Ihnen der Rückgabetyp egal ist.Response<T>
: Passen Sie Response
an Response<T>
-Objekt an und geben Sie es zurückCall<T>
: Führt keine Anpassungsverarbeitung durch und gibt das Call<T>
-Objekt direkt zurückMono<T>
: Reaktiver Rückgabetyp Project Reactor
Single<T>
: Rxjava
responsiver Rückgabetyp (unterstützt Rxjava2/Rxjava3
)Completable
: Reaktionsfähiger Rxjava
Rückgabetyp, HTTP
Anfrage hat keinen Antworttext (unterstützt Rxjava2/Rxjava3
) CallAdapter
kann durch Erben von CallAdapter.Factory
erweitert werden.
Die Komponente unterstützt globale Aufrufadapterfabriken durch die Konfiguration retrofit.global-call-adapter-factories
:
retrofit :
# 全局转换器工厂(组件扩展的`CallAdaptorFactory`工厂已经内置,这里请勿重复配置)
global-call-adapter-factories :
# ...
Für jede Java-Schnittstelle können Sie über @RetrofitClient.callAdapterFactories
auch CallAdapter.Factory
angeben, die von der aktuellen Schnittstelle verwendet wird.
Vorschlag:
CallAdapter.Factory
alsSpring Bean
konfigurieren
Retrofit
verwendet Converter
um das @Body
versehene Objekt in Request Body
und Response Body
in ein Java
Objekt zu konvertieren. Sie können aus den folgenden Converter
wählen:
Die Komponente unterstützt die Konfiguration der globalen Converter.Factory
über retrofit.global-converter-factories
. Der Standardwert ist retrofit2.converter.jackson.JacksonConverterFactory
.
Wenn Sie die Jackson
-Konfiguration ändern müssen, überschreiben Sie einfach die bean
-Konfiguration von JacksonConverterFactory
selbst.
retrofit :
# 全局转换器工厂
global-converter-factories :
- com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory
- retrofit2.converter.jackson.JacksonConverterFactory
Für jede Java
Schnittstelle können Sie über @RetrofitClient.converterFactories
auch Converter.Factory
angeben.
Vorschlag: Konfigurieren Sie
Converter.Factory
alsSpring Bean
.
Anmerkungen wie @RetrofitClient
, @Retry
, @Logging
und @Resilience4jDegrade
unterstützen Metaanmerkungen, Vererbung und @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
Upload-Schnittstelle @ POST ( "upload" )
@ Multipart
Void upload ( @ Part MultipartBody . Part file );
HTTP
-Download-Schnittstelle @ RetrofitClient ( baseUrl = "https://img.ljcdn.com/hc-picture/" )
public interface DownloadApi {
@ GET ( "{fileKey}" )
Response < ResponseBody > download ( @ Path ( "fileKey" ) String fileKey );
}
HTTP
Download-Nutzung @ 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 ();
}
}
Dynamische URLs können mithilfe der @url
-Annotation implementiert werden. Derzeit kann baseUrl
mit jeder zulässigen URL konfiguriert werden. Zum Beispiel: http://github.com/
. Die Laufzeit initiiert nur Anfragen basierend auf der @Url
-Adresse.
Hinweis:
@url
muss an der ersten Position der Methodenparameter platziert werden. Darüber hinaus müssen@GET
,@POST
und andere Anmerkungen den Endpunktpfad nicht definieren.
@ GET
Map < String , Object > test3 ( @ Url String url , @ Query ( "name" ) String name );
DELETE
Anfrage fügt den Anfragetext hinzu @ HTTP ( method = "DELETE" , path = "/user/delete" , hasBody = true )
GET
Anfrage hinzufügen okhttp3
selbst unterstützt das Hinzufügen von Anforderungstexten GET
-Anforderungen nicht. Der Quellcode lautet wie folgt:
Der Autor hat konkrete Gründe angegeben, Sie können sich auf Folgendes beziehen: Problem
Wenn Sie dies jedoch wirklich tun müssen, können Sie Folgendes verwenden: @HTTP(method = "get", path = "/user/get", hasBody = true)
und get
in Kleinbuchstaben verwenden, um die oben genannten Einschränkungen zu umgehen.
Wenn Sie Fragen haben, melden Sie bitte ein Problem oder treten Sie der QQ-Gruppe bei, um Feedback zu erhalten.
Gruppennummer: 806714302