All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feingto.cloud.kit.http.ClientResponse Maven / Gradle / Ivy

There is a newer version: 2.5.2.RELEASE
Show newest version
package com.feingto.cloud.kit.http;

import com.fasterxml.jackson.databind.JsonNode;
import com.feingto.cloud.kit.json.JSON;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;

import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 客户端Http响应
 *
 * @author longfei
 */
@Data
@Accessors(chain = true)
public class ClientResponse implements HttpInputMessage, Closeable {
    public static final String STATUS_CODE_KEY = "code";
    public static final String MESSAGE_KEY = "message";
    public static final HttpHeaders JSON_HEADER = buildHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
    private int statusCode;
    private String message;
    private HttpHeaders headers;
    private InputStream body;
    /**
     * 路由响应结果键, 默认为url最后一个"/"之后的字符串
     */
    private String responseKey;
    private boolean successful;

    private static HttpHeaders buildHeader(String name, String value) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add(name, value);
        return httpHeaders;
    }

    public static ClientResponse success(String result) {
        return success(new ByteArrayInputStream(result.getBytes(StandardCharsets.UTF_8)));
    }

    public static ClientResponse success(InputStream is) {
        return new ClientResponse()
                .setStatusCode(HttpStatus.OK.value())
                .setBody(is)
                .setSuccessful(true);
    }

    public static ClientResponse error(HttpStatus status, String message) {
        JsonNode jsonNode = JSON.JSONObject().put(STATUS_CODE_KEY, status.value()).put(MESSAGE_KEY, message);
        return new ClientResponse()
                .setStatusCode(status.value())
                .setHeaders(JSON_HEADER)
                .setBody(new ByteArrayInputStream(jsonNode.toString().getBytes(StandardCharsets.UTF_8)))
                .setMessage(message)
                .setSuccessful(false);
    }

    public static ClientResponse requestTimeout() {
        return error(HttpStatus.REQUEST_TIMEOUT);
    }

    public static ClientResponse gatewayTimeout() {
        return error(HttpStatus.GATEWAY_TIMEOUT);
    }

    public static ClientResponse badRequest() {
        return error(HttpStatus.BAD_REQUEST);
    }

    public static ClientResponse badGateway() {
        return error(HttpStatus.BAD_GATEWAY);
    }

    public static ClientResponse methodNotAllowed() {
        return error(HttpStatus.METHOD_NOT_ALLOWED);
    }

    public static ClientResponse notFound() {
        return error(HttpStatus.NOT_FOUND);
    }

    public static ClientResponse internalServerError() {
        return error(HttpStatus.INTERNAL_SERVER_ERROR);
    }

    public static ClientResponse serviceUnavailable() {
        return error(HttpStatus.SERVICE_UNAVAILABLE);
    }

    public static ClientResponse unAuthrized() {
        return error(HttpStatus.UNAUTHORIZED);
    }

    public static ClientResponse forbidden() {
        return error(HttpStatus.FORBIDDEN);
    }

    public static ClientResponse tooManyRequests() {
        return error(HttpStatus.TOO_MANY_REQUESTS);
    }

    public static ClientResponse error(HttpStatus status) {
        return error(status, status.getReasonPhrase());
    }

    public static ClientResponse error(String message) {
        return error(HttpStatus.INTERNAL_SERVER_ERROR, message);
    }

    public static ClientResponse merge(List clientResponses) {
        if (Objects.isNull(clientResponses)) {
            return ClientResponse.error("No result return");
        }
        if (clientResponses.stream().anyMatch(Objects::isNull)) {
            return ClientResponse.error("Some requests has no result return");
        }

        return clientResponses.stream()
                .filter(response -> !response.isSuccessful())
                .findFirst()
                .orElseGet(() -> Optional.of(clientResponses)
                        // 单路由
                        .filter(responses -> responses.size() == 1)
                        .map(responses -> Optional.of(responses.get(0))
                                .filter(response -> response.getHeaders().containsKey(HttpHeaders.CONTENT_DISPOSITION))
                                // 不包含二进制头的单路由返回响应结果
                                .orElseGet(() -> ClientResponse
                                        .success(responses.get(0).getBody())
                                        .setHeaders(responses.get(0).getHeaders())))
                        // 多路由
                        .orElseGet(() -> {
                            // 合并响应头
                            MultiValueMap headers = new LinkedMultiValueMap<>();
                            clientResponses.forEach(clientResponse ->
                                    clientResponse.getHeaders().entrySet().stream()
                                            .filter(entry -> !headers.containsKey(entry.getKey()))
                                            .forEach(entry -> headers.put(entry.getKey(), entry.getValue())));

                            // 返回合并后的响应结果
                            return ClientResponse
                                    .success(JSON.reduce(clientResponses.stream()
                                            .map(response -> {
                                                if (StringUtils.hasText(response.getResponseKey())) {
                                                    return JSON.JSONObject()
                                                            .set(response.getResponseKey(), response.getJsonNode());
                                                } else {
                                                    return response.getJsonNode();
                                                }
                                            })
                                            .collect(Collectors.toList())))
                                    .setHeaders(new HttpHeaders(headers));
                        }));
    }

    public String getResponseBody() {
        try (InputStream is = this.body) {
            return StreamUtils.copyToString(is, StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public JsonNode getJsonNode() {
        return Optional.ofNullable(this.getResponseBody())
                .filter(StringUtils::hasText)
                .map(JSON::read)
                .orElse(JSON.JSONObject());
    }

    public void toXml(String contentType) {
        this.body = new ByteArrayInputStream(Optional.of(contentType)
                .filter(it -> it.contains("_"))
                .map(it -> it.split("_"))
                .filter(it -> it.length > 1)
                .map(it -> it[1].toUpperCase())
                .map(it -> String.format("%s", it, System.lineSeparator()))
                .orElse("")
                .concat(Optional.ofNullable(this.getResponseBody())
                        .filter(StringUtils::hasText)
                        .map(JSON::json2xml)
                        .orElse("")).getBytes(StandardCharsets.UTF_8));
    }

    @Override
    public void close() throws IOException {
        if (Objects.nonNull(this.body)) {
            this.body.close();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy