如何根据接口返回类型自动处理响应?

根据接口返回类型自动处理响应

你在请求接口时遇到一个问题,因为你不知道接口返回的类型。对于这种情况,你需要根据返回类型来动态处理响应。

实现此功能的关键在于使用响应头信息,特别是 content-type 头。

import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.publisher.ResponseEntity;

public class DynamicResponseHandling {

    public static Mono> handleResponse(WebClient.RequestHeadersSpec requestSpec) {
        return requestSpec
                .retrieve()
                .onStatus(HttpStatusCode::isError, clientResponse -> clientResponse.createException().flatMap(Mono::error))
                .toEntityFlux(String.class) // 使用 toEntityFlux 而不是 bodyToFlux
                .flatMap(responseEntity -> {
                    HttpHeaders headers2 = responseEntity.getHeaders();
                    MediaType contentType2 = headers2.getContentType();

                    if (MediaType.TEXT_EVENT_STREAM.isCompatibleW

ith(contentType2)) { // 如果是 SSE,则直接返回 Flux 作为响应体 return Mono.just(ResponseEntity.ok() .headers(headers2) .contentType(MediaType.TEXT_EVENT_STREAM) .body(Flux.from(Objects.requireNonNull(responseEntity.getBody())))); } else { // 如果不是 SSE,则根据需要处理响应体 return Objects.requireNonNull(responseEntity.getBody()).reduce("", String::concat) .map(body2 -> ResponseEntity.ok() .headers(headers2) .body(body2)); } }) .onErrorResume(WebClientResponseException.class, e -> { return Mono.just(ResponseEntity.status(e.getStatusCode()) .headers(e.getHeaders()) .body(e.getResponseBodyAsString())); }) .onErrorResume(e -> { // 处理其他异常,并将错误信息添加到响应头中 HttpHeaders errorHeaders = new HttpHeaders(); errorHeaders.set("error-status", "500"); errorHeaders.set("error-message", e.getMessage()); return Mono.just(ResponseEntity.status(500) .headers(errorHeaders) .body(Map.of( "status", "500", "error", "Internal Server Error", "message", e.getMessage() ))); }); } }

通过使用 toentityflux,你可以获取包含 响应体状态码头信息 的完整响应。然后,你可以使用头信息,特别是 content-type,来确定返回的类型,并相应地处理响应。

具体来说,如果你在头信息中检测到 text/event-stream,则这意味着接口返回了服务器端事件(sse)。在这种情况下,返回一个 flux 作为响应,因为 sse 是基于流的协议。

否则,你可以将响应体作为一次性值返回,例如字符串。

这种方法提供了根据接口返回类型动态处理响应的灵活性。