我的 Spring Boot API 正在使用 WebClient 使用第三方 API
演示API控制器
@RestController
public class DemoAPIController
{
@Autowired
DemoService demoService;
@GetMapping("/mytest")
public Mono<UserType> getUserType()
{
return demoService.getUserType();
}
}
演示服务.java
@Component
public class DemoService
{
@Value("${base.url}")
private String baseUrl;
public Mono<UserType> getUserType()
{
System.out.println("baseUrl:" + baseUrl);
WebClient webClient = WebClient.builder().baseUrl(baseUrl)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader("apikey", "test").build();
Mono<UserType> testResult = webClient.get()
.uri("/valic/valic-security-data-api/v1/utility/users/ID873366777/usertype?appName=EAO").retrieve()
.bodyToMono(UserType.class);
testResult.subscribe(value -> System.out.println(value.getUserType()));
return testResult;
}
}
我已经使用 MockWebServer 模拟了第三方 API。当我尝试使用 mockMvc.perform(...) 测试 API 时。我的断言按预期工作。但是在关闭 MockWebServer 时,我收到以下异常
2019-11-29 16:02:43.308 INFO 13048 --- [127.0.0.1:53970] okhttp3.mockwebserver.MockWebServer : MockWebServer[443] received request: GET /valic/valic-security-data-api/v1/utility/users/ID873366777/usertype?appName=EAO HTTP/1.1 and responded: HTTP/1.1 200 OK
2019-11-29 16:03:18.362 INFO 13048 --- [ckWebServer 443] okhttp3.mockwebserver.MockWebServer : MockWebServer[443] done accepting connections: socket closed
2019-11-29 16:03:18.385 WARN 13048 --- [ctor-http-nio-1] r.netty.http.client.HttpClientConnect : [id: 0x186c45c1, L:0.0.0.0/0.0.0.0:53970 ! R:localhost/127.0.0.1:443] The connection observed an error
reactor.netty.http.client.PrematureCloseException: Connection prematurely closed BEFORE response
2019-11-29 16:03:18.389 INFO 13048 --- [127.0.0.1:53970] okhttp3.mockwebserver.MockWebServer : MockWebServer[443] connection from /127.0.0.1 failed: java.net.SocketException: Socket closed
2019-11-29 16:03:20.509 INFO 13048 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
我的测试用例
@ExtendWith(SpringExtension.class)
@WebAppConfiguration()
@ContextConfiguration(classes = WebclientApplication.class)
@SpringBootTest
public class EmployeeServiceMockWebServerTest
{
public static MockWebServer mockWebServer;
private ObjectMapper MAPPER = new ObjectMapper();
public MockMvc mockMvc;
public MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
public MediaType contentTypeURLEncoded = new MediaType(MediaType.APPLICATION_FORM_URLENCODED.getType(),
MediaType.APPLICATION_FORM_URLENCODED.getSubtype(), Charset.forName("utf8"));
@Autowired
private WebApplicationContext webApplicationContext;
@BeforeAll
static void setUp() throws IOException
{
mockWebServer = new MockWebServer();
mockWebServer.start(443);
}
@AfterAll
static void tearDown() throws IOException
{
mockWebServer.shutdown();
}
@BeforeEach
void initialize()
{
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
System.out.println("Hostname:" + mockWebServer.getHostName());
System.out.println("Port:" + mockWebServer.getPort());
}
@Test
void getEmployeeById() throws Exception
{
UserType userType = new UserType();
userType.setUserType("PAR-Mock");
ServiceMessage serviceMessage = new ServiceMessage();
serviceMessage.setCode("200");
serviceMessage.setType("OK");
serviceMessage.setDescription("From Mock");
userType.setServiceMessage(serviceMessage);
mockWebServer.enqueue(
new MockResponse().setBody(MAPPER.writeValueAsString(userType)).addHeader("Content-Type", "application/json"));
mockMvc.perform(get("/mytest").contentType(contentType)).andExpect(status().isOk());
RecordedRequest recordedRequest = mockWebServer.takeRequest();
assertEquals("GET", recordedRequest.getMethod());
assertEquals("/logic/logic-security-data-api/v1/utility/users/ID873366777/usertype?appName=EAO",
recordedRequest.getPath());
}
}
我尝试了其他启动溢出帖子中提到的所有解决方案,但仍然遇到相同的错误。任何帮助表示赞赏。