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

org.smartboot.http.client.HttpRest Maven / Gradle / Ivy

There is a newer version: 1.4.3
Show newest version
/*******************************************************************************
 * Copyright (c) 2017-2021, org.smartboot. All rights reserved.
 * project name: smart-http
 * file name: HttpRest.java
 * Date: 2021-02-07
 * Author: sandao ([email protected])
 ******************************************************************************/

package org.smartboot.http.client;

import org.smartboot.http.client.impl.DefaultHttpResponseHandler;
import org.smartboot.http.client.impl.HttpRequestImpl;
import org.smartboot.http.client.impl.HttpResponseImpl;
import org.smartboot.http.common.enums.HeaderNameEnum;
import org.smartboot.socket.transport.AioSession;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.AbstractQueue;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;

/**
 * @author 三刀([email protected])
 * @version V1.0 , 2021/2/3
 */
public class HttpRest {
    private final static String DEFAULT_USER_AGENT = "smart-http";
    protected final HttpRequestImpl request;
    protected final CompletableFuture completableFuture = new CompletableFuture<>();
    private final AbstractQueue queue;
    private Map queryParams = null;
    private boolean commit = false;
    private Body body;
    /**
     * http body 解码器
     */
    private ResponseHandler responseHandler = new DefaultHttpResponseHandler();
    private final HttpResponseImpl response;

    HttpRest(AioSession session, AbstractQueue queue) {
        this.request = new HttpRequestImpl(session);
        this.queue = queue;
        this.response = new HttpResponseImpl(session, completableFuture);
    }

    protected final void willSendRequest() {
        if (commit) {
            return;
        }
        commit = true;
        resetUri();
        Collection headers = request.getHeaderNames();
        if (!headers.contains(HeaderNameEnum.USER_AGENT.getName())) {
            request.addHeader(HeaderNameEnum.USER_AGENT.getName(), DEFAULT_USER_AGENT);
        }
        response.setResponseHandler(responseHandler);
        AioSession session = response.getSession();
        ResponseAttachment attachment = session.getAttachment();
        synchronized (session) {
            if (attachment.getResponse() == null) {
                attachment.setResponse(response);
                System.out.println("aaaa");
            } else {
                System.out.println("bbb");
                queue.offer(response);
            }
        }
    }

    private void resetUri() {
        if (queryParams == null) {
            return;
        }
        StringBuilder stringBuilder = new StringBuilder(request.getUri());
        int index = request.getUri().indexOf("#");
        if (index > 0) {
            stringBuilder.setLength(index);
        }
        index = request.getUri().indexOf("?");
        if (index == -1) {
            stringBuilder.append('?');
        } else if (index < stringBuilder.length() - 1) {
            stringBuilder.append('&');
        }
        queryParams.forEach((key, value) -> {
            try {
                stringBuilder.append(key).append('=').append(URLEncoder.encode(value, "utf8")).append('&');
            } catch (UnsupportedEncodingException e) {
                stringBuilder.append(key).append('=').append(value).append('&');
            }
        });
        if (stringBuilder.length() > 0) {
            stringBuilder.setLength(stringBuilder.length() - 1);
        }
        request.setUri(stringBuilder.toString());
    }

    public Body body() {
        if (body == null) {
            body = new Body() {

                @Override
                public Body write(byte[] bytes, int offset, int len) {
                    try {
                        willSendRequest();
                        request.getOutputStream().write(bytes, offset, len);
                    } catch (IOException e) {
                        System.out.println("body stream write error! " + e.getMessage());
                        completableFuture.completeExceptionally(e);
                    }
                    return this;
                }

                @Override
                public Body flush() {
                    try {
                        request.getOutputStream().flush();
                    } catch (IOException e) {
                        System.out.println("body stream flush error! " + e.getMessage());
                        e.printStackTrace();
                        completableFuture.completeExceptionally(e);
                    }
                    return this;
                }

                @Override
                public HttpRest done() {
                    return HttpRest.this;
                }
            };
        }
        return body;
    }

    public final Future done() {
        try {
            willSendRequest();
            request.getOutputStream().close();
            request.getOutputStream().flush();
        } catch (Throwable e) {
            completableFuture.completeExceptionally(e);
        }
        return new Future() {
            @Override
            public boolean cancel(boolean mayInterruptIfRunning) {
                return completableFuture.cancel(mayInterruptIfRunning);
            }

            @Override
            public boolean isCancelled() {
                return completableFuture.isCancelled();
            }

            @Override
            public boolean isDone() {
                return completableFuture.isDone();
            }

            @Override
            public HttpResponse get() throws InterruptedException, ExecutionException {
                return completableFuture.get();
            }

            @Override
            public HttpResponse get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
                return completableFuture.get(timeout, unit);
            }

        };
    }

    public HttpRest onSuccess(Consumer consumer) {
        completableFuture.thenAccept(consumer);
        return this;
    }

    public HttpRest onFailure(Consumer consumer) {
        completableFuture.exceptionally(throwable -> {
            consumer.accept(throwable);
            return null;
        });
        return this;
    }

    public HttpRest setMethod(String method) {
        request.setMethod(method);
        return this;
    }


    public Header header() {
        return new Header() {
            @Override
            public Header add(String headerName, String headerValue) {
                request.addHeader(headerName, headerValue);
                return this;
            }

            @Override
            public Header set(String headerName, String headerValue) {
                request.setHeader(headerName, headerValue);
                return this;
            }

            @Override
            public Header setContentType(String contentType) {
                request.setContentType(contentType);
                return this;
            }

            @Override
            public Header setContentLength(int contentLength) {
                request.setContentLength(contentLength);
                return this;
            }

            @Override
            public HttpRest done() {
                return HttpRest.this;
            }
        };
    }

    /**
     * 在 uri 后面添加请求参数
     *
     * @param name  参数名
     * @param value 参数值
     */
    public final HttpRest addQueryParam(String name, String value) {
        if (queryParams == null) {
            queryParams = new HashMap<>();
        }
        queryParams.put(name, value);
        return this;
    }

    /**
     * Http 响应事件
     */
    public HttpRest onResponse(ResponseHandler responseHandler) {
        this.responseHandler = Objects.requireNonNull(responseHandler);
        return this;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy