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

shz.core.api.AbstractApiRequest Maven / Gradle / Ivy

There is a newer version: 10.3.1
Show newest version
package shz.core.api;

import shz.core.*;
import shz.core.AccessibleCacheHelp;
import shz.core.msg.ServerFailureMsg;
import shz.core.FieldSetter;
import shz.core.tuple.Tuple2;

import javax.net.ssl.SSLContext;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * API请求抽象类
 *
 * @param  请求执行参数
 * @param  响应
 */
public abstract class AbstractApiRequest implements ApiRequest {
    @ApiIgnore
    protected final Class tCls;
    @ApiIgnore
    protected final ApiRequestConfig config;
    @ApiIgnore
    protected final Map headers;

    protected AbstractApiRequest() {
        tCls = TypeHelp.getParameterizedType(getClass(), AbstractApiRequest.class, "T", true);
        config = getConfig();
        headers = new HashMap<>();
    }

    protected ApiRequestConfig getConfig() {
        Class cls = getClass();
        ApiConfig apiConfig = cls.getAnnotation(ApiConfig.class);
        ServerFailureMsg.requireNon(apiConfig == null, "API请求类:%s缺少ApiConfig注解", cls.getTypeName());
        ApiRequestConfig config = new ApiRequestConfig();
        config.url = apiConfig.url();
        config.method = apiConfig.method();
        config.proxyHost = apiConfig.proxyHost();
        config.proxyPort = apiConfig.proxyPort();
        config.connectTimeoutMills = apiConfig.connectTimeoutMills();
        config.readTimeoutMills = apiConfig.readTimeoutMills();
        return config;
    }

    @Override
    public final T execute(D data) {
        //获取请求参数
        Map dataMap = dataMap();
        //初始化请求参数
        init(data, dataMap);
        String url = url(dataMap);
        String body = body(dataMap);
        //请求前置方法,可用于日志
        before(url, body);
        try {
            //执行http请求
            String response = read(HttpHelp.requestIs(
                    url, this::sslContext, headers, config.method,
                    body == null ? null : body.getBytes(charset()),
                    config.proxyHost,
                    Integer.parseInt(config.proxyPort),
                    Integer.parseInt(config.connectTimeoutMills),
                    Integer.parseInt(config.readTimeoutMills)
            ));
            //请求后置方法,可用于日志
            after(url, body, response);
            return analysis(response);
        } catch (Exception e) {
            throw PRException.of(e);
        }
    }

    /**
     * 获取请求参数
     */
    private Map dataMap() {
        List fields = AccessibleCacheHelp.fields(getClass(), f -> !ignoreField(f));
        if (fields.isEmpty()) return Collections.emptyMap();
        Map dataMap = ToMap.get(fields.size()).build();
        for (Field field : fields) {
            String name = field.getName();
            Object obj = AccessibleHelp.getField(field, this);

            if (obj == null) {
                ApiValue apiValue = field.getAnnotation(ApiValue.class);
                if (apiValue != null) obj = FieldSetter.parse(apiValue(apiValue.value()), field.getType());
            }

            Tuple2 key = nameFilter(name, obj);
            if (key == null || Help.isTrue(key._1)) continue;
            Tuple2 value = valueFilter(name, obj);
            if (value == null || Help.isTrue(value._1)) continue;
            dataMap.put(key._2, value._2);
        }
        return dataMap.isEmpty() ? Collections.emptyMap() : dataMap;
    }

    protected boolean ignoreField(Field field) {
        return field.isAnnotationPresent(ApiIgnore.class);
    }

    protected String apiValue(String value) {
        return value;
    }

    protected Tuple2 nameFilter(String name, Object value) {
        return Tuple2.apply(Boolean.FALSE, name);
    }

    protected Tuple2 valueFilter(String name, Object value) {
        return Tuple2.apply(value == null, value);
    }

    protected void init(D data, Map dataMap) {
    }

    protected String url(Map dataMap) {
        return config.url;
    }

    protected SSLContext sslContext() {
        return null;
    }

    protected String body(Map dataMap) {
        return null;
    }

    protected Charset charset() {
        return StandardCharsets.UTF_8;
    }

    protected void before(String url, String body) {
    }

    protected String read(InputStream is) {
        return IOHelp.read(IOHelp.getBr(is, charset()));
    }

    protected void after(String url, String body, String response) {
    }

    protected abstract T analysis(String response);
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy