├── .gitignore ├── service-demo ├── src │ ├── main │ │ ├── resources │ │ │ └── application.yaml │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ ├── ServiceDemoApplication.java │ │ │ ├── openservice │ │ │ ├── domain │ │ │ │ └── User.java │ │ │ ├── controller │ │ │ │ ├── DynamicUrlController.java │ │ │ │ └── UserController.java │ │ │ └── service │ │ │ │ └── UserService.java │ │ │ └── config │ │ │ ├── WebAppConfigurer.java │ │ │ └── LoginInterceptor.java │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── openservice │ │ └── service │ │ └── UserServiceTest.java └── pom.xml ├── retrofit-sample ├── src │ └── main │ │ ├── resources │ │ ├── application.yaml │ │ ├── application-v2.3.5.yaml │ │ ├── application-v2.2.3.yaml │ │ ├── application-v2.3.3.yaml │ │ ├── application-v2.3.8.yaml │ │ ├── application-v2.3.1.yaml │ │ ├── application-v2.3.2.yaml │ │ ├── application-v2.2.5.yaml │ │ ├── application-v2.2.11.yaml │ │ ├── application-v2.2.12.yaml │ │ ├── application-v2.2.16.yaml │ │ ├── application-v2.2.17.yaml │ │ ├── application-v2.2.18.yaml │ │ └── application-v2.2.21.yaml │ │ └── java │ │ └── com │ │ └── example │ │ ├── retrofit │ │ ├── domain │ │ │ └── User.java │ │ ├── ext │ │ │ ├── SignInterceptor.java │ │ │ └── Sign.java │ │ ├── remote │ │ │ ├── fallback │ │ │ │ ├── HttpApiFallback.java │ │ │ │ └── HttpDegradeFallbackFactory.java │ │ │ └── HttpApi.java │ │ └── controller │ │ │ └── RetrofitController.java │ │ └── RetrofitSampleApplication.java └── pom.xml ├── Dockerfile ├── .editorconfig ├── README_EN.md ├── README.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | *.iml 3 | target/ 4 | -------------------------------------------------------------------------------- /service-demo/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9000 3 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | profiles: 3 | active: v2.3.8 4 | debug: true 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8u131-jre-alpine 2 | 3 | COPY target/lib/* /app/lib/ 4 | COPY target/helloworld-service-0.0.1-SNAPSHOT.jar /app/app.jar 5 | 6 | ENTRYPOINT ["java", "-jar", "/app/app.jar"] 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 4 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | -------------------------------------------------------------------------------- /README_EN.md: -------------------------------------------------------------------------------- 1 | ## retrofit-spring-boot-starter-demo 2 | --- 3 | 4 | This project is a sample project of [retrofit-spring-boot-starter](https://github.com/LianjiaTech/retrofit-spring-boot-starter). 5 | 6 | 7 | ## Reference Material 8 | 1. [retrofit-spring-boot-starter](https://github.com/LianjiaTech/retrofit-spring-boot-starter) 9 | 2. [https://tianqiapi.com/index/doc?version=v6](https://tianqiapi.com/index/doc?version=v6) 10 | -------------------------------------------------------------------------------- /service-demo/src/main/java/com/example/ServiceDemoApplication.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * Hello world! 8 | */ 9 | @SpringBootApplication 10 | public class ServiceDemoApplication { 11 | public static void main(String[] args) { 12 | SpringApplication.run(ServiceDemoApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/java/com/example/retrofit/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.example.retrofit.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | @Data 10 | @NoArgsConstructor 11 | @AllArgsConstructor 12 | public class User implements Serializable { 13 | private Long id; 14 | private String username; 15 | private int age; 16 | private String password; 17 | } 18 | -------------------------------------------------------------------------------- /service-demo/src/main/java/com/example/openservice/domain/User.java: -------------------------------------------------------------------------------- 1 | package com.example.openservice.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | 10 | @Data 11 | @NoArgsConstructor 12 | @AllArgsConstructor 13 | @Builder 14 | public class User implements Serializable { 15 | private Long id; 16 | private String username; 17 | private int age; 18 | private String password; 19 | } 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## retrofit-spring-boot-starter-demo 2 | --- 3 | 4 | 本项目是 [retrofit-spring-boot-starter](https://github.com/LianjiaTech/retrofit-spring-boot-starter) 的示例项目。 5 | - 示例git地址[retrofit-spring-boot-demo](https://github.com.cnpmjs.org/ismart-yuxi/retrofit-spring-boot-demo.git) 6 | 7 | 本示例分为两模块, 8 | 1. service-demo 演示 基础User服务restful风格的添删改查以及上传 9 | 2. retrofit-sample 演示 通过retrofit-starter搭建的环境调用 User服务的添删改查以及上传,以及 10 | retrofit-starter的诸多特性, 11 | 12 | 例如: 13 | 14 | - [x] 自定义注入OkHttpClient 15 | - [x] 注解式拦截器 16 | - [x] 连接池管理 17 | - [x] 日志打印 18 | - [x] 请求重试 19 | - [x] 错误解码器 20 | - [x] 全局拦截器 21 | - [x] 熔断降级 22 | - [x] 微服务之间的HTTP调用 23 | - [x] 调用适配器 24 | - [x] 数据转换器 25 | 26 | ## 参考资料 27 | 1. [retrofit-spring-boot-starter](https://github.com/LianjiaTech/retrofit-spring-boot-starter) 28 | 2. [https://tianqiapi.com/index/doc?version=v6](https://tianqiapi.com/index/doc?version=v6) 29 | -------------------------------------------------------------------------------- /service-demo/src/main/java/com/example/config/WebAppConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.example.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; 7 | 8 | @Configuration 9 | public class WebAppConfigurer extends WebMvcConfigurationSupport { 10 | 11 | @Bean 12 | LoginInterceptor loginInterceptor() { 13 | return new LoginInterceptor(); 14 | } 15 | 16 | @Override 17 | protected void addInterceptors(InterceptorRegistry registry) { 18 | registry.addInterceptor(loginInterceptor()) 19 | .addPathPatterns("/**").excludePathPatterns("/openservice/download"); 20 | super.addInterceptors(registry); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/java/com/example/retrofit/ext/SignInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.example.retrofit.ext; 2 | 3 | import com.github.lianjiatech.retrofit.spring.boot.interceptor.BasePathMatchInterceptor; 4 | import lombok.Data; 5 | import okhttp3.Interceptor; 6 | import okhttp3.Request; 7 | import okhttp3.Response; 8 | import org.springframework.stereotype.Component; 9 | 10 | import java.io.IOException; 11 | 12 | @Component 13 | @Data 14 | public class SignInterceptor extends BasePathMatchInterceptor { 15 | 16 | private String accessKeyId; 17 | 18 | private String accessKeySecret; 19 | 20 | @Override 21 | public Response doIntercept(Interceptor.Chain chain) throws IOException { 22 | Request request = chain.request(); 23 | Request newReq = request.newBuilder() 24 | .addHeader("accessKeyId", accessKeyId) 25 | .addHeader("accessKeySecret", accessKeySecret) 26 | .build(); 27 | return chain.proceed(newReq); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /service-demo/src/main/java/com/example/openservice/controller/DynamicUrlController.java: -------------------------------------------------------------------------------- 1 | package com.example.openservice.controller; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | 12 | /** 13 | * 演示动态url 请求 14 | */ 15 | @Slf4j 16 | @RestController 17 | @RequestMapping("/openservice/") 18 | public class DynamicUrlController { 19 | 20 | 21 | @GetMapping("/dynamic1/url1/") 22 | public Map dynamicUrl1(String name) { 23 | Map map = new HashMap<>(); 24 | map.clear(); 25 | map.put("dynamicUrl1", "/dynamic1/url1/" + name); 26 | return map; 27 | } 28 | 29 | @GetMapping("/dynamic2/url2/") 30 | public Map dynamicUrl2(String name) { 31 | Map map = new HashMap<>(); 32 | map.clear(); 33 | map.put("dynamicUrl2", "/dynamic2/url2/" + name); 34 | return map; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 2.7.0 10 | 11 | 12 | 13 | retrofit-spring-boot-demo 14 | com.example 15 | retrofit 16 | 0.0.1 17 | pom 18 | Demo project for Spring Boot 19 | 20 | 21 | 22 | 8 23 | 8 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | service-demo 34 | retrofit-sample 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/java/com/example/retrofit/ext/Sign.java: -------------------------------------------------------------------------------- 1 | package com.example.retrofit.ext; 2 | 3 | import com.github.lianjiatech.retrofit.spring.boot.interceptor.BasePathMatchInterceptor; 4 | import com.github.lianjiatech.retrofit.spring.boot.interceptor.InterceptMark; 5 | 6 | import java.lang.annotation.*; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.TYPE) 10 | @Documented 11 | @InterceptMark 12 | public @interface Sign { 13 | /** 14 | * 密钥key 15 | * 支持占位符形式配置。 16 | * 17 | * @return 18 | */ 19 | String accessKeyId(); 20 | 21 | /** 22 | * 密钥 23 | * 支持占位符形式配置。 24 | * 25 | * @return 26 | */ 27 | String accessKeySecret(); 28 | 29 | /** 30 | * 拦截器匹配路径 31 | * 32 | * @return 33 | */ 34 | String[] include() default {"/**"}; 35 | 36 | /** 37 | * 拦截器排除匹配,排除指定路径拦截 38 | * 39 | * @return 40 | */ 41 | String[] exclude() default {}; 42 | 43 | /** 44 | * 处理该注解的拦截器类 45 | * 优先从spring容器获取对应的Bean,如果获取不到,则使用反射创建一个! 46 | * 47 | * @return 48 | */ 49 | Class handler() default SignInterceptor.class; 50 | } 51 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.3.5.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂(已经内置了组件扩展的转换器工厂,这里请勿重复配置) 15 | global-converter-factories: 16 | - retrofit2.converter.jackson.JacksonConverterFactory 17 | # 全局调用适配器工厂(已经内置了组件扩展的调用适配器工厂,这里请勿重复配置) 18 | global-call-adapter-factories: 19 | # 全局日志打印配置 20 | global-log: 21 | # 启用全局日志打印 22 | enable: true 23 | # 全局日志打印级别 24 | log-level: info 25 | # 全局日志打印策略 26 | log-strategy: body 27 | 28 | 29 | # 全局重试配置 30 | global-retry: 31 | # 是否启用全局重试 32 | enable: true 33 | # 全局重试间隔时间 34 | interval-ms: 10 35 | # 全局最大重试次数 36 | max-retries: 1 37 | # 全局重试规则 38 | retry-rules: 39 | - response_status_not_2xx 40 | - occur_io_exception 41 | 42 | # 熔断降级配置 43 | degrade: 44 | # 熔断降级类型。默认none,表示不启用熔断降级 45 | degrade-type: sentinel 46 | global-sentinel-degrade: 47 | # 是否开启 48 | enable: true 49 | # 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N) 50 | count: 500 51 | 52 | test: 53 | baseUrl: http://localhost:9000/openservice/ 54 | accessKeyId: sdfsdfdsf 55 | accessKeySecret: sadfsadfsdfsdf 56 | -------------------------------------------------------------------------------- /service-demo/src/main/java/com/example/config/LoginInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.example.config; 2 | 3 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpServletResponse; 7 | import java.io.IOException; 8 | import java.io.PrintWriter; 9 | 10 | public class LoginInterceptor extends HandlerInterceptorAdapter { 11 | @Override 12 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 13 | String accessKeyId = request.getHeader("accessKeyId"); 14 | String accessKeySecret = request.getHeader("accessKeySecret"); 15 | 16 | if (null == accessKeyId || "".equals(accessKeyId) || null == accessKeySecret || "".equals(accessKeySecret)) { 17 | error(response, "缺少头部信息"); 18 | return false; 19 | } 20 | return super.preHandle(request, response, handler); 21 | } 22 | 23 | /** 24 | * 错误信息 25 | * 26 | * @param response 27 | * @param msg 28 | */ 29 | private void error(HttpServletResponse response, String msg) { 30 | response.setCharacterEncoding("utf-8"); 31 | response.setHeader("Content-Type", "application/json"); 32 | try { 33 | PrintWriter writer = response.getWriter(); 34 | //将返回的错误提示压入流中 35 | writer.write(msg); 36 | writer.flush(); 37 | } catch (IOException e) { 38 | e.printStackTrace(); 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /service-demo/src/main/java/com/example/openservice/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.example.openservice.service; 2 | 3 | import com.example.openservice.domain.User; 4 | import org.springframework.stereotype.Service; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collection; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | @Service 12 | public class UserService { 13 | 14 | private static final Map MOCK_DB_DATA = new HashMap<>(); 15 | 16 | static { 17 | User _user1 = User.builder().id(10000L).age(23).username("username1").password("dddddddddddddddddddddd").build(); 18 | User _user2 = User.builder().id(10001L).age(24).username("username2").password("hhhhhhhhhhhhhh").build(); 19 | User _user3 = User.builder().id(10002L).age(25).username("username3").password("mmmmmmmmmmmmmmm").build(); 20 | 21 | MOCK_DB_DATA.put(10000L, _user1); 22 | MOCK_DB_DATA.put(10001L, _user2); 23 | MOCK_DB_DATA.put(10002L, _user3); 24 | } 25 | 26 | 27 | public void addUser(User user) { 28 | Long key = System.currentTimeMillis(); 29 | user.setId(key); 30 | MOCK_DB_DATA.put(key, user); 31 | } 32 | 33 | public void updateUser(User user) { 34 | MOCK_DB_DATA.replace(user.getId(), user); 35 | } 36 | 37 | public void deleteUser(Long id) { 38 | MOCK_DB_DATA.remove(id); 39 | } 40 | 41 | public Collection AllUser() { 42 | return new ArrayList<>(MOCK_DB_DATA.values()); 43 | } 44 | 45 | public User user(Long id) { 46 | return MOCK_DB_DATA.get(id); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.2.3.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 启用日志打印 15 | enable-log: true 16 | # 连接池配置 17 | pool: 18 | test1: 19 | max-idle-connections: 3 20 | keep-alive-second: 100 21 | test2: 22 | max-idle-connections: 5 23 | keep-alive-second: 50 24 | # 禁用void返回值类型 25 | disable-void-return-type: false 26 | # 日志打印拦截器 27 | logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor 28 | # 请求重试拦截器 29 | retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor 30 | # 全局转换器工厂 31 | global-converter-factories: 32 | - retrofit2.converter.jackson.JacksonConverterFactory 33 | # 全局调用适配器工厂 34 | global-call-adapter-factories: 35 | - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory 36 | - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory 37 | # 是否启用熔断降级 38 | enable-degrade: true 39 | # 熔断降级实现方式 40 | degrade-type: sentinel 41 | # 熔断资源名称解析器 42 | resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser 43 | 44 | test: 45 | baseUrl: http://localhost:9000/openservice/ 46 | accessKeyId: sdfsdfdsf 47 | accessKeySecret: sadfsadfsdfsdf 48 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/java/com/example/retrofit/remote/fallback/HttpApiFallback.java: -------------------------------------------------------------------------------- 1 | package com.example.retrofit.remote.fallback; 2 | 3 | import com.example.retrofit.domain.User; 4 | import com.example.retrofit.remote.HttpApi; 5 | import okhttp3.MultipartBody; 6 | import okhttp3.ResponseBody; 7 | import org.springframework.stereotype.Component; 8 | import retrofit2.Call; 9 | import retrofit2.Response; 10 | 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | @Component 15 | public class HttpApiFallback implements HttpApi { 16 | 17 | @Override 18 | public Response user(Long id) { 19 | return null; 20 | } 21 | 22 | @Override 23 | public Call> users() { 24 | return null; 25 | } 26 | 27 | @Override 28 | public Call addUser(User user) { 29 | return null; 30 | } 31 | 32 | @Override 33 | public Call updateUser(User user) { 34 | return null; 35 | } 36 | 37 | @Override 38 | public Call deleteUser(Long id) { 39 | return null; 40 | } 41 | 42 | @Override 43 | public Call upload(List files) { 44 | return null; 45 | } 46 | 47 | 48 | @Override 49 | public Response> dynamicUrl(String url, String name) { 50 | return null; 51 | } 52 | 53 | @Override 54 | public Response download() { 55 | return null; 56 | } 57 | 58 | @Override 59 | public String returnValueString() { 60 | return null; 61 | } 62 | 63 | @Override 64 | public Boolean returnValueBoolean() { 65 | return null; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.3.3.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂 15 | global-converter-factories: 16 | - com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory 17 | - retrofit2.converter.jackson.JacksonConverterFactory 18 | # 全局调用适配器工厂 19 | global-call-adapter-factories: 20 | - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory 21 | - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory 22 | 23 | # 全局日志打印配置 24 | global-log: 25 | # 启用全局日志打印 26 | enable: true 27 | # 全局日志打印级别 28 | log-level: info 29 | # 全局日志打印策略 30 | log-strategy: body 31 | 32 | 33 | # 全局重试配置 34 | global-retry: 35 | # 是否启用全局重试 36 | enable: true 37 | # 全局重试间隔时间 38 | interval-ms: 10 39 | # 全局最大重试次数 40 | max-retries: 1 41 | # 全局重试规则 42 | retry-rules: 43 | - response_status_not_2xx 44 | - occur_io_exception 45 | 46 | # 熔断降级配置 47 | degrade: 48 | # 熔断降级类型。默认none,表示不启用熔断降级 49 | degrade-type: sentinel 50 | global-sentinel-degrade: 51 | # 是否开启 52 | enable: true 53 | # 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N) 54 | count: 500 55 | 56 | test: 57 | baseUrl: http://localhost:9000/openservice/ 58 | accessKeyId: sdfsdfdsf 59 | accessKeySecret: sadfsadfsdfsdf 60 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.3.8.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂(已经内置了组件扩展的转换器工厂,这里请勿重复配置) 15 | global-converter-factories: 16 | - retrofit2.converter.jackson.JacksonConverterFactory 17 | # 全局调用适配器工厂(已经内置了组件扩展的调用适配器工厂,这里请勿重复配置) 18 | global-call-adapter-factories: 19 | # 全局日志打印配置 20 | global-log: 21 | # 启用全局日志打印 22 | enable: true 23 | # 全局日志打印级别 24 | log-level: info 25 | # 全局日志打印策略 26 | log-strategy: body 27 | 28 | 29 | # 全局重试配置 30 | global-retry: 31 | # 是否启用全局重试 32 | enable: true 33 | # 全局重试间隔时间 34 | interval-ms: 10 35 | # 全局最大重试次数 36 | max-retries: 1 37 | # 全局重试规则 38 | retry-rules: 39 | - response_status_not_2xx 40 | - occur_io_exception 41 | 42 | # 全局超时时间配置 43 | global-timeout: 44 | # 全局读取超时时间 45 | read-timeout-ms: 5000 46 | # 全局写入超时时间 47 | write-timeout-ms: 5000 48 | # 全局连接超时时间 49 | connect-timeout-ms: 5000 50 | # 全局完整调用超时时间 51 | call-timeout-ms: 0 52 | 53 | # 熔断降级配置 54 | degrade: 55 | # 熔断降级类型。默认none,表示不启用熔断降级 56 | degrade-type: sentinel 57 | global-sentinel-degrade: 58 | # 是否开启 59 | enable: true 60 | # 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N) 61 | count: 500 62 | 63 | test: 64 | baseUrl: http://localhost:9000/openservice/ 65 | accessKeyId: sdfsdfdsf 66 | accessKeySecret: sadfsadfsdfsdf 67 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/java/com/example/RetrofitSampleApplication.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import okhttp3.ConnectionPool; 4 | import okhttp3.Dispatcher; 5 | import org.springframework.boot.SpringApplication; 6 | import org.springframework.boot.autoconfigure.SpringBootApplication; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Primary; 9 | 10 | import lombok.extern.slf4j.Slf4j; 11 | import okhttp3.OkHttpClient; 12 | 13 | import java.util.concurrent.TimeUnit; 14 | 15 | /** 16 | * Hello world! 17 | */ 18 | @SpringBootApplication 19 | @Slf4j 20 | public class RetrofitSampleApplication { 21 | public static void main(String[] args) { 22 | SpringApplication.run(RetrofitSampleApplication.class, args); 23 | } 24 | 25 | @Bean 26 | @Primary 27 | OkHttpClient defaultBaseOkHttpClient() { 28 | return new OkHttpClient.Builder() 29 | .addInterceptor(chain -> { 30 | log.info("=======替换默认的BaseOkHttpClient====="); 31 | return chain.proceed(chain.request()); 32 | }) 33 | .build(); 34 | } 35 | 36 | @Bean 37 | OkHttpClient testOkHttpClient() { 38 | Dispatcher dispatcher = new Dispatcher(); 39 | dispatcher.setMaxRequests(100); 40 | dispatcher.setMaxRequestsPerHost(10); 41 | 42 | return new OkHttpClient.Builder() 43 | .readTimeout(1, TimeUnit.SECONDS) 44 | .writeTimeout(1, TimeUnit.SECONDS) 45 | .connectTimeout(1, TimeUnit.SECONDS) 46 | .dispatcher(dispatcher) 47 | .connectionPool(new ConnectionPool(10, 10, TimeUnit.MINUTES)) 48 | .addInterceptor(chain -> { 49 | log.info("=======使用testOkHttpClientBuilder构建的OkHttpClient====="); 50 | return chain.proceed(chain.request()); 51 | }) 52 | .build(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.3.1.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂 15 | global-converter-factories: 16 | - com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory 17 | - retrofit2.converter.jackson.JacksonConverterFactory 18 | # 全局调用适配器工厂 19 | global-call-adapter-factories: 20 | - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory 21 | - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory 22 | 23 | # 日志打印配置 24 | log: 25 | # 启用日志打印 26 | enable-global-log: true 27 | # 全局日志打印级别 28 | global-log-level: info 29 | # 全局日志打印策略 30 | global-log-strategy: basic 31 | 32 | # 重试配置 33 | retry: 34 | # 是否启用全局重试 35 | enable-global-retry: false 36 | # 全局重试间隔时间 37 | global-interval-ms: 100 38 | # 全局最大重试次数 39 | global-max-retries: 2 40 | # 全局重试规则 41 | global-retry-rules: 42 | - response_status_not_2xx 43 | - occur_io_exception 44 | 45 | # 熔断降级配置 46 | degrade: 47 | # 熔断降级类型。默认none,表示不启用熔断降级 48 | degrade-type: sentinel 49 | 50 | # 全局连接超时时间 51 | global-connect-timeout-ms: 10000 52 | # 全局读取超时时间 53 | global-read-timeout-ms: 10000 54 | # 全局写入超时时间 55 | global-write-timeout-ms: 10000 56 | # 全局完整调用超时时间 57 | global-call-timeout-ms: 0 58 | pool: 59 | test1: 60 | max-idle-connections: 3 61 | keep-alive-second: 100 62 | test2: 63 | max-idle-connections: 5 64 | keep-alive-second: 50 65 | test: 66 | baseUrl: http://localhost:9000/openservice/ 67 | accessKeyId: sdfsdfdsf 68 | accessKeySecret: sadfsadfsdfsdf 69 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.3.2.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂 15 | global-converter-factories: 16 | - com.github.lianjiatech.retrofit.spring.boot.core.BasicTypeConverterFactory 17 | - retrofit2.converter.jackson.JacksonConverterFactory 18 | # 全局调用适配器工厂 19 | global-call-adapter-factories: 20 | - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory 21 | - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory 22 | 23 | # 全局日志打印配置 24 | global-log: 25 | # 启用全局日志打印 26 | enable: true 27 | # 全局日志打印级别 28 | log-level: info 29 | # 全局日志打印策略 30 | log-strategy: body 31 | 32 | 33 | # 全局重试配置 34 | global-retry: 35 | # 是否启用全局重试 36 | enable: true 37 | # 全局重试间隔时间 38 | interval-ms: 10 39 | # 全局最大重试次数 40 | max-retries: 1 41 | # 全局重试规则 42 | retry-rules: 43 | - response_status_not_2xx 44 | - occur_io_exception 45 | 46 | # 熔断降级配置 47 | degrade: 48 | # 熔断降级类型。默认none,表示不启用熔断降级 49 | degrade-type: sentinel 50 | global-sentinel-degrade: 51 | # 是否开启 52 | enable: true 53 | # 各降级策略对应的阈值。平均响应时间(ms),异常比例(0-1),异常数量(1-N) 54 | count: 500 55 | 56 | # 全局连接超时时间 57 | global-connect-timeout-ms: 10000 58 | # 全局读取超时时间 59 | global-read-timeout-ms: 10000 60 | # 全局写入超时时间 61 | global-write-timeout-ms: 10000 62 | # 全局完整调用超时时间 63 | global-call-timeout-ms: 0 64 | pool: 65 | test1: 66 | max-idle-connections: 3 67 | keep-alive-second: 100 68 | test2: 69 | max-idle-connections: 5 70 | keep-alive-second: 50 71 | test: 72 | baseUrl: http://localhost:9000/openservice/ 73 | accessKeyId: sdfsdfdsf 74 | accessKeySecret: sadfsadfsdfsdf 75 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/java/com/example/retrofit/remote/fallback/HttpDegradeFallbackFactory.java: -------------------------------------------------------------------------------- 1 | package com.example.retrofit.remote.fallback; 2 | 3 | import com.example.retrofit.domain.User; 4 | import com.example.retrofit.remote.HttpApi; 5 | import com.github.lianjiatech.retrofit.spring.boot.degrade.FallbackFactory; 6 | import lombok.extern.slf4j.Slf4j; 7 | import okhttp3.MultipartBody; 8 | import okhttp3.ResponseBody; 9 | import org.springframework.stereotype.Component; 10 | import retrofit2.Call; 11 | import retrofit2.Response; 12 | 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * @author Administrator 18 | */ 19 | @Component 20 | @Slf4j 21 | public class HttpDegradeFallbackFactory implements FallbackFactory { 22 | @Override 23 | public HttpApi create(Throwable cause) { 24 | log.error("触发熔断了! {0} {1}", cause.getMessage(), cause); 25 | return new HttpApi() { 26 | @Override 27 | public Response user(Long id) { 28 | return null; 29 | } 30 | 31 | @Override 32 | public Call> users() { 33 | return null; 34 | } 35 | 36 | @Override 37 | public Call addUser(User user) { 38 | return null; 39 | } 40 | 41 | @Override 42 | public Call updateUser(User user) { 43 | return null; 44 | } 45 | 46 | @Override 47 | public Call deleteUser(Long id) { 48 | return null; 49 | } 50 | 51 | @Override 52 | public Call upload(List files) { 53 | return null; 54 | } 55 | 56 | @Override 57 | public Response> dynamicUrl(String url, String name) { 58 | return null; 59 | } 60 | 61 | @Override 62 | public Response download() { 63 | return null; 64 | } 65 | 66 | @Override 67 | public String returnValueString() { 68 | return null; 69 | } 70 | 71 | @Override 72 | public Boolean returnValueBoolean() { 73 | return null; 74 | } 75 | }; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.2.5.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂 15 | # retrofit-spring-boot-starter支持通过retrofit.global-converter-factories配置全局数据转换器工厂, 16 | # 转换器工厂实例优先从Spring容器获取,如果没有获取到,则反射创建。 17 | # 默认的全局数据转换器工厂是retrofit2.converter.jackson.JacksonConverterFactory, 18 | # 你可以直接通过spring.jackson.*配置jackson序列化规则,配置可参考Customize the Jackson ObjectMapper! 19 | global-converter-factories: 20 | - retrofit2.converter.jackson.JacksonConverterFactory 21 | # 全局调用适配器工厂 22 | global-call-adapter-factories: 23 | - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory 24 | - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory 25 | # 熔断降级配置 26 | degrade: 27 | # 是否启用熔断降级 28 | enable: true 29 | # 熔断降级实现方式 30 | degrade-type: sentinel 31 | # 熔断资源名称解析器 32 | resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser 33 | # 重试配置 34 | retry: 35 | # 是否启用全局重试 2.2.5 新增 36 | enable-global-retry: true 37 | # 全局重试间隔时间 2.2.5 新增 38 | global-interval-ms: 20 39 | # 全局最大重试次数 2.2.5 新增 40 | global-max-retries: 10 41 | # 全局重试规则 2.2.5 新增 42 | global-retry-rules: 43 | - response_status_not_2xx 44 | # 重试拦截器 45 | retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor 46 | # 日志打印配置 47 | log: 48 | # 启用日志打印 49 | enable: true 50 | # 日志打印拦截器 51 | logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor 52 | # 连接池配置 53 | # 默认情况下,所有通过Retrofit发送的http请求都会使用max-idle-connections=5 keep-alive-second=300的默认连接池。 54 | # 当然,我们也可以在配置文件中配置多个自定义的连接池,然后通过 55 | # @RetrofitClient的poolName属性来指定使用。比如我们要让某个接口下的请求全部使用poolName=test1的连接池, 56 | pool: 57 | test1: 58 | max-idle-connections: 3 59 | keep-alive-second: 100 60 | test2: 61 | max-idle-connections: 5 62 | keep-alive-second: 50 63 | test: 64 | baseUrl: http://localhost:9000/openservice/ 65 | accessKeyId: sdfsdfdsf 66 | accessKeySecret: sadfsadfsdfsdf 67 | -------------------------------------------------------------------------------- /service-demo/src/test/java/com/example/openservice/service/UserServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.example.openservice.service; 2 | 3 | import com.example.openservice.domain.User; 4 | import com.fasterxml.jackson.core.JsonProcessingException; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.BeforeAll; 8 | import org.junit.jupiter.api.BeforeEach; 9 | import org.junit.jupiter.api.Test; 10 | import org.mockito.InjectMocks; 11 | import org.mockito.MockitoAnnotations; 12 | 13 | import java.util.Collection; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | //@TestInstance(value = TestInstance.Lifecycle.PER_CLASS) 18 | class UserServiceTest { 19 | 20 | static Map MOCK_DB_DATA = new HashMap<>(); 21 | 22 | 23 | @BeforeAll 24 | static void initData() { 25 | User _user1 = User.builder().id(10000L).age(23).username("username1").password("dddddddddddddddddddddd").build(); 26 | User _user2 = User.builder().id(10001L).age(24).username("username2").password("hhhhhhhhhhhhhh").build(); 27 | User _user3 = User.builder().id(10002L).age(25).username("username3").password("mmmmmmmmmmmmmmm").build(); 28 | 29 | MOCK_DB_DATA.put(10000L, _user1); 30 | MOCK_DB_DATA.put(10001L, _user2); 31 | MOCK_DB_DATA.put(10002L, _user3); 32 | } 33 | 34 | @InjectMocks 35 | UserService userService; 36 | 37 | @BeforeEach 38 | void setUp() { 39 | MockitoAnnotations.initMocks(this); 40 | } 41 | 42 | 43 | @Test 44 | void testAddUser() { 45 | userService.addUser(new User(10004L, "username", 0, "password")); 46 | } 47 | 48 | @Test 49 | void testUpdateUser() { 50 | userService.updateUser(new User(10001L, "username", 0, "password")); 51 | } 52 | 53 | @Test 54 | void testDeleteUser() { 55 | userService.deleteUser(10002L); 56 | // Assertions.assertDoesNotThrow(); 57 | } 58 | 59 | @Test 60 | void testAllUser() { 61 | Collection result = userService.AllUser(); 62 | Assertions.assertEquals(MOCK_DB_DATA.size()+1, result.size()); 63 | } 64 | 65 | @Test 66 | void testUser() throws JsonProcessingException { 67 | User result = userService.user(10000L); 68 | ObjectMapper om = new ObjectMapper(); 69 | String resultStr = om.writeValueAsString(result); 70 | String MockDataStr = om.writeValueAsString(MOCK_DB_DATA.get(10000L)); 71 | Assertions.assertEquals(MockDataStr, resultStr); 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.2.11.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂 15 | # retrofit-spring-boot-starter支持通过retrofit.global-converter-factories配置全局数据转换器工厂, 16 | # 转换器工厂实例优先从Spring容器获取,如果没有获取到,则反射创建。 17 | # 默认的全局数据转换器工厂是retrofit2.converter.jackson.JacksonConverterFactory, 18 | # 你可以直接通过spring.jackson.*配置jackson序列化规则,配置可参考Customize the Jackson ObjectMapper! 19 | global-converter-factories: 20 | - retrofit2.converter.jackson.JacksonConverterFactory 21 | # 全局调用适配器工厂 22 | global-call-adapter-factories: 23 | - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory 24 | - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory 25 | # 熔断降级配置 26 | degrade: 27 | # 是否启用熔断降级 28 | enable: true 29 | # 熔断降级实现方式 30 | degrade-type: sentinel 31 | # 熔断资源名称解析器 32 | resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser 33 | # 全局连接超时时间 34 | global-connect-timeout-ms: 5000 35 | # 全局读取超时时间 36 | global-read-timeout-ms: 5000 37 | # 全局写入超时时间 38 | global-write-timeout-ms: 5000 39 | # 全局完整调用超时时间 40 | global-call-timeout-ms: 0 41 | # 重试配置 42 | retry: 43 | # 是否启用全局重试 2.2.5 新增 44 | enable-global-retry: true 45 | # 全局重试间隔时间 2.2.5 新增 46 | global-interval-ms: 20 47 | # 全局最大重试次数 2.2.5 新增 48 | global-max-retries: 10 49 | # 全局重试规则 2.2.5 新增 50 | global-retry-rules: 51 | - response_status_not_2xx 52 | # 重试拦截器 53 | retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor 54 | # 日志打印配置 55 | log: 56 | # 启用日志打印 57 | enable: true 58 | # 日志打印拦截器 59 | logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor 60 | # 连接池配置 61 | # 默认情况下,所有通过Retrofit发送的http请求都会使用max-idle-connections=5 keep-alive-second=300的默认连接池。 62 | # 当然,我们也可以在配置文件中配置多个自定义的连接池,然后通过 63 | # @RetrofitClient的poolName属性来指定使用。比如我们要让某个接口下的请求全部使用poolName=test1的连接池, 64 | pool: 65 | test1: 66 | max-idle-connections: 3 67 | keep-alive-second: 100 68 | test2: 69 | max-idle-connections: 5 70 | keep-alive-second: 50 71 | test: 72 | baseUrl: http://localhost:9000/openservice/ 73 | accessKeyId: sdfsdfdsf 74 | accessKeySecret: sadfsadfsdfsdf 75 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.2.12.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂 15 | # retrofit-spring-boot-starter支持通过retrofit.global-converter-factories配置全局数据转换器工厂, 16 | # 转换器工厂实例优先从Spring容器获取,如果没有获取到,则反射创建。 17 | # 默认的全局数据转换器工厂是retrofit2.converter.jackson.JacksonConverterFactory, 18 | # 你可以直接通过spring.jackson.*配置jackson序列化规则,配置可参考Customize the Jackson ObjectMapper! 19 | global-converter-factories: 20 | - retrofit2.converter.jackson.JacksonConverterFactory 21 | # 全局调用适配器工厂 22 | global-call-adapter-factories: 23 | - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory 24 | - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory 25 | # 熔断降级配置 26 | degrade: 27 | # 是否启用熔断降级 28 | enable: true 29 | # 熔断降级实现方式 30 | degrade-type: sentinel 31 | # 熔断资源名称解析器 32 | resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser 33 | # 全局连接超时时间 2.2.11 新增 34 | global-connect-timeout-ms: 5000 35 | # 全局读取超时时间 2.2.11 新增 36 | global-read-timeout-ms: 5000 37 | # 全局写入超时时间 2.2.11 新增 38 | global-write-timeout-ms: 5000 39 | # 全局完整调用超时时间 2.2.11 新增 40 | global-call-timeout-ms: 0 41 | # 重试配置 42 | retry: 43 | # 是否启用全局重试 2.2.5 新增 44 | enable-global-retry: true 45 | # 全局重试间隔时间 2.2.5 新增 46 | global-interval-ms: 20 47 | # 全局最大重试次数 2.2.5 新增 48 | global-max-retries: 10 49 | # 全局重试规则 2.2.5 新增 50 | global-retry-rules: 51 | - response_status_not_2xx 52 | # 重试拦截器 53 | retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor 54 | # 日志打印配置 55 | log: 56 | # 启用日志打印 57 | enable: true 58 | # 日志打印拦截器 59 | logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor 60 | # 全局日志打印级别 2.2.6 新增 61 | global-log-level: info 62 | # 全局日志打印策略 2.2.6 新增 63 | global-log-strategy: body 64 | # 连接池配置 65 | # 默认情况下,所有通过Retrofit发送的http请求都会使用max-idle-connections=5 keep-alive-second=300的默认连接池。 66 | # 当然,我们也可以在配置文件中配置多个自定义的连接池,然后通过 67 | # @RetrofitClient的poolName属性来指定使用。比如我们要让某个接口下的请求全部使用poolName=test1的连接池, 68 | pool: 69 | test1: 70 | max-idle-connections: 3 71 | keep-alive-second: 100 72 | test2: 73 | max-idle-connections: 5 74 | keep-alive-second: 50 75 | test: 76 | baseUrl: http://localhost:9000/openservice/ 77 | accessKeyId: sdfsdfdsf 78 | accessKeySecret: sadfsadfsdfsdf 79 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.2.16.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂 15 | # retrofit-spring-boot-starter支持通过retrofit.global-converter-factories配置全局数据转换器工厂, 16 | # 转换器工厂实例优先从Spring容器获取,如果没有获取到,则反射创建。 17 | # 默认的全局数据转换器工厂是retrofit2.converter.jackson.JacksonConverterFactory, 18 | # 你可以直接通过spring.jackson.*配置jackson序列化规则,配置可参考Customize the Jackson ObjectMapper! 19 | global-converter-factories: 20 | - retrofit2.converter.jackson.JacksonConverterFactory 21 | # 全局调用适配器工厂 22 | global-call-adapter-factories: 23 | - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory 24 | - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory 25 | # 熔断降级配置 26 | degrade: 27 | # 是否启用熔断降级 28 | enable: true 29 | # 熔断降级实现方式 30 | degrade-type: sentinel 31 | # 熔断资源名称解析器 32 | resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser 33 | # 全局连接超时时间 2.2.11 新增 34 | global-connect-timeout-ms: 5000 35 | # 全局读取超时时间 2.2.11 新增 36 | global-read-timeout-ms: 5000 37 | # 全局写入超时时间 2.2.11 新增 38 | global-write-timeout-ms: 5000 39 | # 全局完整调用超时时间 2.2.11 新增 40 | global-call-timeout-ms: 0 41 | # 重试配置(默认关闭) 42 | retry: 43 | # 是否启用全局重试 2.2.5 新增 44 | # 2.2.16 之后默认关闭 45 | enable-global-retry: true 46 | # 全局重试间隔时间 2.2.5 新增 47 | global-interval-ms: 20 48 | # 全局最大重试次数 2.2.5 新增 49 | global-max-retries: 10 50 | # 全局重试规则 2.2.5 新增 51 | global-retry-rules: 52 | - response_status_not_2xx 53 | # 重试拦截器 54 | retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor 55 | # 日志打印配置 56 | log: 57 | # 启用日志打印 58 | enable: true 59 | # 日志打印拦截器 60 | logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor 61 | # 全局日志打印级别 2.2.6 新增 62 | global-log-level: info 63 | # 全局日志打印策略 2.2.6 新增 64 | global-log-strategy: body 65 | # 连接池配置 66 | # 默认情况下,所有通过Retrofit发送的http请求都会使用max-idle-connections=5 keep-alive-second=300的默认连接池。 67 | # 当然,我们也可以在配置文件中配置多个自定义的连接池,然后通过 68 | # @RetrofitClient的poolName属性来指定使用。比如我们要让某个接口下的请求全部使用poolName=test1的连接池, 69 | pool: 70 | test1: 71 | max-idle-connections: 3 72 | keep-alive-second: 100 73 | test2: 74 | max-idle-connections: 5 75 | keep-alive-second: 50 76 | test: 77 | baseUrl: http://localhost:9000/openservice/ 78 | accessKeyId: sdfsdfdsf 79 | accessKeySecret: sadfsadfsdfsdf 80 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.2.17.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂 15 | # retrofit-spring-boot-starter支持通过retrofit.global-converter-factories配置全局数据转换器工厂, 16 | # 转换器工厂实例优先从Spring容器获取,如果没有获取到,则反射创建。 17 | # 默认的全局数据转换器工厂是retrofit2.converter.jackson.JacksonConverterFactory, 18 | # 你可以直接通过spring.jackson.*配置jackson序列化规则,配置可参考Customize the Jackson ObjectMapper! 19 | global-converter-factories: 20 | - retrofit2.converter.jackson.JacksonConverterFactory 21 | # 全局调用适配器工厂 22 | global-call-adapter-factories: 23 | - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory 24 | - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory 25 | # 熔断降级配置 26 | degrade: 27 | # 是否启用熔断降级 28 | enable: true 29 | # 熔断降级实现方式 30 | degrade-type: sentinel 31 | # 熔断资源名称解析器 32 | resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser 33 | # 全局连接超时时间 2.2.11 新增 34 | global-connect-timeout-ms: 5000 35 | # 全局读取超时时间 2.2.11 新增 36 | global-read-timeout-ms: 5000 37 | # 全局写入超时时间 2.2.11 新增 38 | global-write-timeout-ms: 5000 39 | # 全局完整调用超时时间 2.2.11 新增 40 | global-call-timeout-ms: 0 41 | # 重试配置(默认关闭) 42 | retry: 43 | # 是否启用全局重试 2.2.5 新增 44 | # 2.2.16 之后默认关闭 45 | enable-global-retry: true 46 | # 全局重试间隔时间 2.2.5 新增 47 | global-interval-ms: 20 48 | # 全局最大重试次数 2.2.5 新增 49 | global-max-retries: 10 50 | # 全局重试规则 2.2.5 新增 51 | global-retry-rules: 52 | - response_status_not_2xx 53 | # 重试拦截器 54 | retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor 55 | # 日志打印配置 56 | log: 57 | # 启用日志打印 58 | enable: true 59 | # 日志打印拦截器 60 | logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor 61 | # 全局日志打印级别 2.2.6 新增 62 | global-log-level: info 63 | # 全局日志打印策略 2.2.6 新增 64 | global-log-strategy: body 65 | # 连接池配置 66 | # 默认情况下,所有通过Retrofit发送的http请求都会使用max-idle-connections=5 keep-alive-second=300的默认连接池。 67 | # 当然,我们也可以在配置文件中配置多个自定义的连接池,然后通过 68 | # @RetrofitClient的poolName属性来指定使用。比如我们要让某个接口下的请求全部使用poolName=test1的连接池, 69 | pool: 70 | test1: 71 | max-idle-connections: 3 72 | keep-alive-second: 100 73 | test2: 74 | max-idle-connections: 5 75 | keep-alive-second: 50 76 | test: 77 | baseUrl: http://localhost:9000/openservice/ 78 | accessKeyId: sdfsdfdsf 79 | accessKeySecret: sadfsadfsdfsdf 80 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.2.18.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂 15 | # retrofit-spring-boot-starter支持通过retrofit.global-converter-factories配置全局数据转换器工厂, 16 | # 转换器工厂实例优先从Spring容器获取,如果没有获取到,则反射创建。 17 | # 默认的全局数据转换器工厂是retrofit2.converter.jackson.JacksonConverterFactory, 18 | # 你可以直接通过spring.jackson.*配置jackson序列化规则,配置可参考Customize the Jackson ObjectMapper! 19 | global-converter-factories: 20 | - retrofit2.converter.jackson.JacksonConverterFactory 21 | # 全局调用适配器工厂 22 | global-call-adapter-factories: 23 | - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory 24 | - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory 25 | # 熔断降级配置 26 | degrade: 27 | # 是否启用熔断降级 28 | enable: true 29 | # 熔断降级实现方式 30 | degrade-type: sentinel 31 | # 熔断资源名称解析器 32 | resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser 33 | # 全局连接超时时间 2.2.11 新增 34 | global-connect-timeout-ms: 5000 35 | # 全局读取超时时间 2.2.11 新增 36 | global-read-timeout-ms: 5000 37 | # 全局写入超时时间 2.2.11 新增 38 | global-write-timeout-ms: 5000 39 | # 全局完整调用超时时间 2.2.11 新增 40 | global-call-timeout-ms: 0 41 | # 重试配置(默认关闭) 42 | retry: 43 | # 是否启用全局重试 2.2.5 新增 44 | # 2.2.16 之后默认关闭 45 | enable-global-retry: true 46 | # 全局重试间隔时间 2.2.5 新增 47 | global-interval-ms: 20 48 | # 全局最大重试次数 2.2.5 新增 49 | global-max-retries: 10 50 | # 全局重试规则 2.2.5 新增 51 | global-retry-rules: 52 | - response_status_not_2xx 53 | # 重试拦截器 54 | retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor 55 | # 日志打印配置 56 | log: 57 | # 启用日志打印 58 | enable: true 59 | # 日志打印拦截器 60 | logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor 61 | # 全局日志打印级别 2.2.6 新增 62 | global-log-level: info 63 | # 全局日志打印策略 2.2.6 新增 64 | global-log-strategy: body 65 | # 连接池配置 66 | # 默认情况下,所有通过Retrofit发送的http请求都会使用max-idle-connections=5 keep-alive-second=300的默认连接池。 67 | # 当然,我们也可以在配置文件中配置多个自定义的连接池,然后通过 68 | # @RetrofitClient的poolName属性来指定使用。比如我们要让某个接口下的请求全部使用poolName=test1的连接池, 69 | pool: 70 | test1: 71 | max-idle-connections: 3 72 | keep-alive-second: 100 73 | test2: 74 | max-idle-connections: 5 75 | keep-alive-second: 50 76 | test: 77 | baseUrl: http://localhost:9000/openservice/ 78 | accessKeyId: sdfsdfdsf 79 | accessKeySecret: sadfsadfsdfsdf 80 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/resources/application-v2.2.21.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | spring: 5 | application: 6 | name: retrofit-sample 7 | # 在springcloud开发环境下,请启用相应的jar包,详情看maven pom的注释 8 | # cloud: 9 | # sentinel: 10 | # transport: 11 | # dashboard: localhost:8080 12 | # heartbeat-interval-ms: 500 13 | retrofit: 14 | # 全局转换器工厂 15 | # retrofit-spring-boot-starter支持通过retrofit.global-converter-factories配置全局数据转换器工厂, 16 | # 转换器工厂实例优先从Spring容器获取,如果没有获取到,则反射创建。 17 | # 默认的全局数据转换器工厂是retrofit2.converter.jackson.JacksonConverterFactory, 18 | # 你可以直接通过spring.jackson.*配置jackson序列化规则,配置可参考Customize the Jackson ObjectMapper! 19 | global-converter-factories: 20 | - retrofit2.converter.jackson.JacksonConverterFactory 21 | # 全局调用适配器工厂 22 | global-call-adapter-factories: 23 | - com.github.lianjiatech.retrofit.spring.boot.core.BodyCallAdapterFactory 24 | - com.github.lianjiatech.retrofit.spring.boot.core.ResponseCallAdapterFactory 25 | # 熔断降级配置 26 | degrade: 27 | # 是否启用熔断降级 28 | enable: true 29 | # 熔断降级实现方式 30 | degrade-type: sentinel 31 | # 熔断资源名称解析器 32 | resource-name-parser: com.github.lianjiatech.retrofit.spring.boot.degrade.DefaultResourceNameParser 33 | # 全局连接超时时间 2.2.11 新增 34 | global-connect-timeout-ms: 5000 35 | # 全局读取超时时间 2.2.11 新增 36 | global-read-timeout-ms: 5000 37 | # 全局写入超时时间 2.2.11 新增 38 | global-write-timeout-ms: 5000 39 | # 全局完整调用超时时间 2.2.11 新增 40 | global-call-timeout-ms: 0 41 | # 重试配置(默认关闭) 42 | retry: 43 | # 是否启用全局重试 2.2.5 新增 44 | # 2.2.16 之后默认关闭 45 | enable-global-retry: true 46 | # 全局重试间隔时间 2.2.5 新增 47 | global-interval-ms: 20 48 | # 全局最大重试次数 2.2.5 新增 49 | global-max-retries: 10 50 | # 全局重试规则 2.2.5 新增 51 | global-retry-rules: 52 | - response_status_not_2xx 53 | # 重试拦截器 54 | retry-interceptor: com.github.lianjiatech.retrofit.spring.boot.retry.DefaultRetryInterceptor 55 | # 日志打印配置 56 | log: 57 | # 启用日志打印 58 | enable: true 59 | # 日志打印拦截器 60 | logging-interceptor: com.github.lianjiatech.retrofit.spring.boot.interceptor.DefaultLoggingInterceptor 61 | # 全局日志打印级别 2.2.6 新增 62 | global-log-level: info 63 | # 全局日志打印策略 2.2.6 新增 64 | global-log-strategy: body 65 | # 连接池配置 66 | # 默认情况下,所有通过Retrofit发送的http请求都会使用max-idle-connections=5 keep-alive-second=300的默认连接池。 67 | # 当然,我们也可以在配置文件中配置多个自定义的连接池,然后通过 68 | # @RetrofitClient的poolName属性来指定使用。比如我们要让某个接口下的请求全部使用poolName=test1的连接池, 69 | pool: 70 | test1: 71 | max-idle-connections: 3 72 | keep-alive-second: 100 73 | test2: 74 | max-idle-connections: 5 75 | keep-alive-second: 50 76 | test: 77 | baseUrl: http://localhost:9000/openservice/ 78 | accessKeyId: sdfsdfdsf 79 | accessKeySecret: sadfsadfsdfsdf 80 | -------------------------------------------------------------------------------- /service-demo/src/main/java/com/example/openservice/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.example.openservice.controller; 2 | 3 | import com.example.openservice.domain.User; 4 | import com.example.openservice.service.UserService; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.HttpHeaders; 8 | import org.springframework.http.HttpStatus; 9 | import org.springframework.http.MediaType; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.util.ResourceUtils; 12 | import org.springframework.web.bind.annotation.*; 13 | import org.springframework.web.multipart.MultipartFile; 14 | 15 | import java.io.File; 16 | import java.io.IOException; 17 | import java.net.URLDecoder; 18 | import java.nio.charset.StandardCharsets; 19 | import java.nio.file.Files; 20 | import java.nio.file.Path; 21 | import java.util.Arrays; 22 | import java.util.List; 23 | import java.util.Objects; 24 | 25 | @Slf4j 26 | @RestController 27 | @RequestMapping("/openservice/") 28 | public class UserController { 29 | 30 | @Autowired 31 | private UserService userService; 32 | 33 | @PostMapping("/user") 34 | public String addUser(@RequestBody User user) { 35 | userService.addUser(user); 36 | return "add success"; 37 | } 38 | 39 | @PutMapping("/user") 40 | public String updateUser(@RequestBody User user) { 41 | userService.updateUser(user); 42 | return "update success"; 43 | } 44 | 45 | @DeleteMapping("/user/{id}") 46 | public String deleteUser(@PathVariable Long id) { 47 | userService.deleteUser(id); 48 | return "delete success"; 49 | } 50 | 51 | @GetMapping("/user/{id}") 52 | public User user(@PathVariable Long id) { 53 | return userService.user(id); 54 | } 55 | 56 | @GetMapping("/user") 57 | public List users() { 58 | return (List) userService.AllUser(); 59 | } 60 | 61 | 62 | @GetMapping("/download") 63 | public ResponseEntity download() throws IOException { 64 | String dfileName = new String("file_download".getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8); 65 | HttpHeaders headers = new HttpHeaders(); 66 | headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); 67 | headers.setContentDispositionFormData("attachment", dfileName); 68 | Path filePath = ResourceUtils.getFile("classpath:application.yaml").toPath(); 69 | return new ResponseEntity<>(Files.readAllBytes(filePath), headers, HttpStatus.CREATED); 70 | } 71 | 72 | 73 | @PostMapping("/upload") 74 | public String upload(@RequestParam("files") MultipartFile[] files) { 75 | Arrays.stream(files).forEach(file -> { 76 | if (!file.isEmpty()) { 77 | try { 78 | String fileName = URLDecoder.decode(Objects.requireNonNull(file.getOriginalFilename()), StandardCharsets.UTF_8.name()); 79 | String filePath = "D:/"; 80 | File dest = new File(filePath + fileName); 81 | file.transferTo(dest); 82 | log.info("上传成功"); 83 | } catch (IOException e) { 84 | e.printStackTrace(); 85 | } 86 | } 87 | }); 88 | return "上传成功"; 89 | } 90 | 91 | @GetMapping("/returnValueString") 92 | public String returnValueString() { 93 | return System.currentTimeMillis() + ""; 94 | } 95 | 96 | 97 | @GetMapping("/returnValueBoolean") 98 | public Boolean returnValueBoolean() { 99 | return Boolean.TRUE; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/java/com/example/retrofit/remote/HttpApi.java: -------------------------------------------------------------------------------- 1 | package com.example.retrofit.remote; 2 | 3 | 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import com.example.retrofit.domain.User; 8 | import com.example.retrofit.ext.Sign; 9 | import com.example.retrofit.remote.fallback.HttpApiFallback; 10 | import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient; 11 | import com.github.lianjiatech.retrofit.spring.boot.degrade.sentinel.SentinelDegrade; 12 | import com.github.lianjiatech.retrofit.spring.boot.log.LogStrategy; 13 | import com.github.lianjiatech.retrofit.spring.boot.log.Logging; 14 | 15 | import okhttp3.MultipartBody; 16 | import okhttp3.ResponseBody; 17 | import retrofit2.Call; 18 | import retrofit2.Response; 19 | import retrofit2.http.Body; 20 | import retrofit2.http.DELETE; 21 | import retrofit2.http.GET; 22 | import retrofit2.http.Multipart; 23 | import retrofit2.http.POST; 24 | import retrofit2.http.PUT; 25 | import retrofit2.http.Part; 26 | import retrofit2.http.Path; 27 | import retrofit2.http.Query; 28 | import retrofit2.http.Url; 29 | 30 | /** 31 | * v2.2.0 增加熔断器 32 | * v2.2.14 未配置baseUrl并且未配置serviceId忽视该接口注册(baseurl 和 serviceId 必选一个) 33 | * v2.2.15 ========> 2.1.13和2.2.14对于配置中心有bug,回退到2.2.12版本或升级到2.2.17 34 | * v2.2.16 默认关闭全局请求重试 35 | * v2.2.17 修复RetrofitClient在Apollo配置中心出现的bug(其中@RetrofitClient去掉@service注解) 36 | * 37 | * 38 | * https://github.com/LianjiaTech/retrofit-spring-boot-starter#%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7 39 | * 40 | * @author wangyuxi 41 | * @date 2020/08/24 42 | **/ 43 | 44 | /* 45 | * 46 | * 拦截器顺序为标记的顺序,其中全局过滤器排在最后 47 | * 48 | * 49 | */ 50 | 51 | //@Sign 52 | ///*2.2.2 @Intercept支持多拦截器配置*/ 53 | //@Intercept(handler = TimeStampInterceptor.class, include = {"/api/**"}) 54 | //@Intercept(handler = AnotherTimeStampInterceptor.class, include = {"/api/**"}) 55 | 56 | /** 57 | * 请求重试 58 | * retrofit-spring-boot-starter支持请求重试功能,只需要在接口或者方法上加上@Retry注解即可。 59 | * @Retry支持重试次数maxRetries、重试时间间隔intervalMs以及重试规则retryRules配置。重试规则支持三种配置: 60 | * 61 | * RESPONSE_STATUS_NOT_2XX:响应状态码不是2xx时执行重试; 62 | * OCCUR_IO_EXCEPTION:发生IO异常时执行重试; 63 | * OCCUR_EXCEPTION:发生任意异常时执行重试; 64 | * 默认响应状态码不是2xx或者发生IO异常时自动进行重试。需要的话,你也可以继承BaseRetryInterceptor实现自己的请求重试拦截器,然后将其配置上去。 65 | * 66 | * 67 | * logStrategy = LogStrategy.BODY 把请求第三方接口的收到的返回值,打印出日志 68 | * 69 | */ 70 | @RetrofitClient(baseUrl = "${test.baseUrl}", fallback = HttpApiFallback.class, connectTimeoutMs = 3000) 71 | @Sign(accessKeyId = "${test.accessKeyId}", accessKeySecret = "${test.accessKeySecret}") 72 | @Logging(logStrategy = LogStrategy.BODY) 73 | /*默认策略情况下,每5s平均响应时间不得超过500ms,否则启用熔断降级*/ 74 | @SentinelDegrade(count = 500) 75 | public interface HttpApi { 76 | 77 | /** 78 | * 方法上的路径不以/开头 79 | *

80 | *

@Query("id") Long id

81 | * 对于Retrofit而言,方法上的/开头表示直接接在domain后面的端点。 82 | */ 83 | @GET("user/{id}") 84 | Response user(@Path("id") Long id); 85 | 86 | @GET("user") 87 | Call> users(); 88 | 89 | @POST("user") 90 | Call addUser(@Body User user); 91 | 92 | @PUT("user") 93 | Call updateUser(@Body User user); 94 | 95 | @DELETE("user/{id}") 96 | Call deleteUser(@Path("id") Long id); 97 | 98 | @POST("upload") 99 | @Multipart 100 | Call upload(@Part List files); 101 | 102 | /** 103 | * 使用@url注解可实现动态URL。 104 | * 105 | * 注意:@url必须放在方法参数的第一个位置。原有定义@GET、@POST等注解上,不需要定义端点路径! 106 | * 107 | * @param url 108 | * @param name 109 | * @return 110 | */ 111 | @GET 112 | Response> dynamicUrl(@Url String url, @Query("name") String name); 113 | 114 | 115 | /** 116 | * 调用下载 117 | * @return Response 118 | */ 119 | @GET("download") 120 | Response download(); 121 | 122 | /** 123 | * v2.2.10 支持基础类型(`String`/`Long`/`Integer`/`Boolean`/`Float`/`Double`)作为接口返回值 124 | */ 125 | @GET("returnValueString") 126 | String returnValueString(); 127 | 128 | /** 129 | * v2.2.10 支持基础类型(`String`/`Long`/`Integer`/`Boolean`/`Float`/`Double`)作为接口返回值 130 | */ 131 | @GET("returnValueBoolean") 132 | Boolean returnValueBoolean(); 133 | } 134 | -------------------------------------------------------------------------------- /service-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | 8 | com.example 9 | retrofit 10 | 0.0.1 11 | 12 | 13 | com.example 14 | service-demo 15 | 0.0.1 16 | service-demo 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-web 29 | 30 | 31 | 32 | org.projectlombok 33 | lombok 34 | 35 | 36 | 37 | org.junit.jupiter 38 | junit-jupiter-api 39 | test 40 | 41 | 42 | 43 | org.mockito 44 | mockito-junit-jupiter 45 | test 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | maven-clean-plugin 56 | 3.1.0 57 | 58 | 59 | 60 | maven-resources-plugin 61 | 3.0.2 62 | 63 | 64 | maven-compiler-plugin 65 | 3.8.0 66 | 67 | 68 | maven-surefire-plugin 69 | 2.22.1 70 | 71 | 72 | maven-jar-plugin 73 | 3.0.2 74 | 75 | 76 | maven-install-plugin 77 | 2.5.2 78 | 79 | 80 | maven-deploy-plugin 81 | 2.8.2 82 | 83 | 84 | 85 | maven-site-plugin 86 | 3.7.1 87 | 88 | 89 | maven-project-info-reports-plugin 90 | 3.0.0 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | org.junit 99 | junit-bom 100 | 5.8.1 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /retrofit-sample/src/main/java/com/example/retrofit/controller/RetrofitController.java: -------------------------------------------------------------------------------- 1 | package com.example.retrofit.controller; 2 | 3 | import com.example.retrofit.domain.User; 4 | import com.example.retrofit.remote.HttpApi; 5 | import lombok.extern.slf4j.Slf4j; 6 | import okhttp3.MultipartBody; 7 | import org.springframework.web.bind.annotation.*; 8 | import org.springframework.web.multipart.MultipartFile; 9 | 10 | import java.io.File; 11 | import java.io.FileOutputStream; 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.net.URLEncoder; 15 | import java.nio.charset.StandardCharsets; 16 | import java.util.Arrays; 17 | import java.util.Objects; 18 | import java.util.UUID; 19 | 20 | import static java.lang.System.out; 21 | 22 | @RestController 23 | @Slf4j 24 | @RequestMapping(value = "/retrofit/") 25 | public class RetrofitController { 26 | 27 | private final HttpApi httpApi; 28 | 29 | public RetrofitController(HttpApi httpApi) { 30 | this.httpApi = httpApi; 31 | } 32 | 33 | @GetMapping("/user") 34 | public String userPerformed() throws IOException { 35 | User user = new User(); 36 | user.setAge(23); 37 | user.setPassword("123456"); 38 | user.setUsername("xxzx"); 39 | 40 | httpApi.addUser(user).execute(); 41 | 42 | Objects.requireNonNull(httpApi.users().execute().body()).forEach(x -> { 43 | out.println(x.toString()); 44 | }); 45 | 46 | user.setId(10000L); 47 | user.setUsername("KKKKKKKKKKKKKKKKKK"); 48 | user.setPassword("asdfasdfsadfsdf"); 49 | user.setAge(60); 50 | out.println(new String(Objects.requireNonNull(httpApi.updateUser(user).execute().body()).bytes())); 51 | 52 | Objects.requireNonNull(httpApi.users().execute().body()).forEach(x -> { 53 | out.println(x.toString()); 54 | }); 55 | 56 | out.println(httpApi.user(10000L)); 57 | 58 | out.println(new String(Objects.requireNonNull(httpApi.deleteUser(1608823107168L).execute().body()).bytes())); 59 | 60 | 61 | // 二进制流 62 | InputStream is = Objects.requireNonNull(httpApi.download().body()).byteStream(); 63 | 64 | saveFile(is); 65 | 66 | return "success"; 67 | } 68 | 69 | private void saveFile(InputStream is) throws IOException { 70 | // 具体如何处理二进制流,由业务自行控制。这里以写入文件为例 71 | File tempDirectory = new File("temp"); 72 | if (!tempDirectory.exists()) { 73 | tempDirectory.mkdir(); 74 | } 75 | File file = new File(tempDirectory, UUID.randomUUID().toString()); 76 | if (!file.exists()) { 77 | file.createNewFile(); 78 | } 79 | FileOutputStream fos = new FileOutputStream(file); 80 | byte[] b = new byte[1024]; 81 | int length; 82 | while ((length = is.read(b)) > 0) { 83 | fos.write(b, 0, length); 84 | } 85 | is.close(); 86 | fos.close(); 87 | } 88 | 89 | @GetMapping("/dynamicUrlPerformed") 90 | public boolean dynamicUrlPerformed() { 91 | boolean dynamicUrl1 = httpApi.dynamicUrl("http://localhost:9000/openservice/dynamic1/url1/", "url1").body().get("dynamicUrl1").equals("/dynamic1/url1/url1"); 92 | boolean dynamicUrl2 = httpApi.dynamicUrl("http://localhost:9000/openservice/dynamic2/url2/", "url2").body().get("dynamicUrl2").equals("/dynamic2/url2/url2"); 93 | return dynamicUrl1 && dynamicUrl2; 94 | } 95 | 96 | @PostMapping("/upload") 97 | public String upload(@RequestParam("files") MultipartFile[] files) throws IOException { 98 | final MultipartBody.Builder builder = new MultipartBody.Builder(); 99 | builder.setType(MultipartBody.FORM); 100 | Arrays.stream(files).forEach(file -> { 101 | // 对文件名使用URLEncoder进行编码 102 | try { 103 | String fileName = URLEncoder.encode(Objects.requireNonNull(file.getOriginalFilename()), StandardCharsets.UTF_8.name()); 104 | okhttp3.RequestBody requestBody = okhttp3.RequestBody.create(MultipartBody.FORM, file.getBytes()); 105 | builder.addFormDataPart("files", fileName, requestBody); 106 | } catch (IOException e) { 107 | e.printStackTrace(); 108 | } 109 | }); 110 | httpApi.upload(builder.build().parts()).execute(); 111 | return "success"; 112 | } 113 | 114 | @GetMapping("/testReturnString") 115 | public String testReturnString() { 116 | String val = httpApi.returnValueString(); 117 | log.info(val); 118 | return val; 119 | } 120 | 121 | @GetMapping("/testReturnBoolean") 122 | public Boolean testReturnBoolean() { 123 | Boolean apiBoolean = httpApi.returnValueBoolean(); 124 | log.info(String.valueOf(apiBoolean)); 125 | return apiBoolean; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /retrofit-sample/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | 8 | 9 | com.example 10 | retrofit 11 | 0.0.1 12 | 13 | 14 | retrofit-sample 15 | 0.0.1 16 | 17 | retrofit-sample 18 | 19 | 20 | UTF-8 21 | 1.8 22 | 1.8 23 | 24 | 25 | 26 | 27 | 28 | org.springframework.boot 29 | spring-boot-starter-web 30 | 31 | 32 | 33 | com.github.lianjiatech 34 | retrofit-spring-boot-starter 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 2.3.8 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | com.alibaba.csp 88 | sentinel-core 89 | 1.6.3 90 | 91 | 92 | 93 | org.projectlombok 94 | lombok 95 | true 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | maven-clean-plugin 106 | 3.1.0 107 | 108 | 109 | 110 | maven-resources-plugin 111 | 3.0.2 112 | 113 | 114 | maven-compiler-plugin 115 | 3.8.0 116 | 117 | 118 | maven-surefire-plugin 119 | 2.22.1 120 | 121 | 122 | maven-jar-plugin 123 | 3.0.2 124 | 125 | 126 | maven-install-plugin 127 | 2.5.2 128 | 129 | 130 | maven-deploy-plugin 131 | 2.8.2 132 | 133 | 134 | 135 | maven-site-plugin 136 | 3.7.1 137 | 138 | 139 | maven-project-info-reports-plugin 140 | 3.0.0 141 | 142 | 143 | 144 | 145 | 146 | --------------------------------------------------------------------------------