Skip to content

Commit 83d54ad

Browse files
BodyCallAdapterFactory支持非2xx响应体转换
1 parent 24dec75 commit 83d54ad

File tree

7 files changed

+152
-10
lines changed

7 files changed

+152
-10
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<dependency>
4343
<groupId>com.github.lianjiatech</groupId>
4444
<artifactId>retrofit-spring-boot-starter</artifactId>
45-
<version>2.1.7</version>
45+
<version>2.1.8</version>
4646
</dependency>
4747
```
4848

README_CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
<dependency>
4242
<groupId>com.github.lianjiatech</groupId>
4343
<artifactId>retrofit-spring-boot-starter</artifactId>
44-
<version>2.1.7</version>
44+
<version>2.1.8</version>
4545
</dependency>
4646
```
4747

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.lianjiatech</groupId>
88
<artifactId>retrofit-spring-boot-starter</artifactId>
9-
<version>2.1.7</version>
9+
<version>2.1.8</version>
1010

1111
<name>retrofit-spring-boot-starter</name>
1212
<description>retrofit-spring-boot-starter</description>

src/main/java/com/github/lianjiatech/retrofit/spring/boot/core/BodyCallAdapterFactory.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@
1717

1818
import com.github.lianjiatech.retrofit.spring.boot.exception.RetrofitException;
1919
import okhttp3.Request;
20-
import retrofit2.Call;
21-
import retrofit2.CallAdapter;
22-
import retrofit2.Response;
23-
import retrofit2.Retrofit;
20+
import okhttp3.ResponseBody;
21+
import retrofit2.*;
2422

2523
import java.io.IOException;
2624
import java.lang.annotation.Annotation;
@@ -49,15 +47,21 @@ public final class BodyCallAdapterFactory extends CallAdapter.Factory {
4947
if (Response.class.isAssignableFrom(getRawType(returnType))) {
5048
return null;
5149
}
52-
return new BodyCallAdapter(returnType);
50+
return new BodyCallAdapter(returnType, annotations, retrofit);
5351
}
5452

5553
final class BodyCallAdapter<R> implements CallAdapter<R, R> {
5654

5755
private Type returnType;
5856

59-
BodyCallAdapter(Type returnType) {
57+
private Retrofit retrofit;
58+
59+
private Annotation[] annotations;
60+
61+
BodyCallAdapter(Type returnType, Annotation[] annotations, Retrofit retrofit) {
6062
this.returnType = returnType;
63+
this.retrofit = retrofit;
64+
this.annotations = annotations;
6165
}
6266

6367
@Override
@@ -74,7 +78,21 @@ public R adapt(Call<R> call) {
7478
} catch (IOException e) {
7579
throw Objects.requireNonNull(RetrofitException.errorExecuting(request, e));
7680
}
77-
return response.body();
81+
82+
if (response.isSuccessful()) {
83+
return response.body();
84+
}
85+
86+
ResponseBody errorBody = response.errorBody();
87+
if (errorBody == null) {
88+
return null;
89+
}
90+
Converter<ResponseBody, R> converter = retrofit.responseBodyConverter(responseType(), annotations);
91+
try {
92+
return converter.convert(Objects.requireNonNull(errorBody));
93+
} catch (IOException e) {
94+
throw Objects.requireNonNull(RetrofitException.errorExecuting(request, e));
95+
}
7896
}
7997
}
8098
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.github.lianjiatech.retrofit.spring.boot.test;
2+
3+
import com.fasterxml.jackson.annotation.JsonInclude;
4+
import com.fasterxml.jackson.core.JsonProcessingException;
5+
import com.fasterxml.jackson.databind.DeserializationFeature;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person;
8+
import com.github.lianjiatech.retrofit.spring.boot.test.entity.Result;
9+
import com.github.lianjiatech.retrofit.spring.boot.test.http.ErrorDecoderTestApi;
10+
import okhttp3.mockwebserver.MockResponse;
11+
import okhttp3.mockwebserver.MockWebServer;
12+
import org.junit.After;
13+
import org.junit.Before;
14+
import org.junit.Test;
15+
import org.junit.runner.RunWith;
16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
18+
import org.springframework.beans.factory.annotation.Autowired;
19+
import org.springframework.boot.test.context.SpringBootTest;
20+
import org.springframework.test.context.junit4.SpringRunner;
21+
22+
import java.io.IOException;
23+
import java.util.HashMap;
24+
import java.util.Map;
25+
26+
/**
27+
* @author 陈添明
28+
*/
29+
@SpringBootTest(classes = RetrofitTestApplication.class)
30+
@RunWith(SpringRunner.class)
31+
public class ErrorDecoderTest {
32+
33+
34+
private static final Logger logger = LoggerFactory.getLogger(RetrofitExceptionTest.class);
35+
36+
@Autowired
37+
private ErrorDecoderTestApi errorDecoderTestApi;
38+
39+
private MockWebServer server;
40+
41+
private static final ObjectMapper objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
42+
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
43+
44+
@Before
45+
public void before() throws IOException {
46+
System.out.println("=========开启MockWebServer===========");
47+
server = new MockWebServer();
48+
server.start(8080);
49+
50+
}
51+
52+
@After
53+
public void after() throws IOException {
54+
System.out.println("=========关闭MockWebServer===========");
55+
server.close();
56+
}
57+
58+
59+
@Test
60+
public void test() throws JsonProcessingException {
61+
// mock
62+
Person mockPerson = new Person().setId(1L)
63+
.setName("test")
64+
.setAge(10);
65+
66+
Result mockResult = new Result<>()
67+
.setCode(0)
68+
.setMsg("ok")
69+
.setData(objectMapper.writeValueAsString(mockPerson));
70+
MockResponse response = new MockResponse()
71+
.setResponseCode(500)
72+
.addHeader("Content-Type", "application/json; charset=utf-8")
73+
.addHeader("Cache-Control", "no-cache")
74+
.setBody(objectMapper.writeValueAsString(mockResult));
75+
server.enqueue(response);
76+
77+
Person person = new Person().setId(1L).setName("test").setAge(10);
78+
Person error = errorDecoderTestApi.error(person);
79+
System.out.println(error);
80+
81+
}
82+
83+
84+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.github.lianjiatech.retrofit.spring.boot.test;
2+
3+
import com.github.lianjiatech.retrofit.spring.boot.core.ErrorDecoder;
4+
import okhttp3.Request;
5+
import okhttp3.Response;
6+
7+
/**
8+
* @author 陈添明
9+
*/
10+
public class InvalidRespErrorDecoder implements ErrorDecoder {
11+
12+
@Override
13+
public RuntimeException invalidRespDecode(Request request, Response response) {
14+
return null;
15+
}
16+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.github.lianjiatech.retrofit.spring.boot.test.http;
2+
3+
import com.github.lianjiatech.retrofit.spring.boot.annotation.RetrofitClient;
4+
import com.github.lianjiatech.retrofit.spring.boot.interceptor.LogStrategy;
5+
import com.github.lianjiatech.retrofit.spring.boot.test.InvalidRespErrorDecoder;
6+
import com.github.lianjiatech.retrofit.spring.boot.test.entity.Person;
7+
import retrofit2.http.Body;
8+
import retrofit2.http.POST;
9+
10+
/**
11+
* @author 陈添明
12+
*/
13+
@RetrofitClient(baseUrl = "${test.baseUrl}", logStrategy = LogStrategy.BODY, errorDecoder = InvalidRespErrorDecoder.class)
14+
public interface ErrorDecoderTestApi {
15+
16+
/**
17+
* .
18+
*
19+
* @param person .
20+
* @return .
21+
*/
22+
@POST("error")
23+
Person error(@Body Person person);
24+
}

0 commit comments

Comments
 (0)