手写HTTP网络请求框架

作者: 进击de小黑 | 来源:发表于2018-12-17 14:37 被阅读10次

    创建基于HttpUrlConnection的具体获取网络数据流HttpUrlConnectionUtil

    public class HttpUrlConnectionUtil {
    
        public static ByteArrayOutputStream execute(Request request) throws HttpException {
            switch (request.requestMethod) {
                case GET:
                    return get(request);
                case POST:
                    return post(request);
            }
            return null;
        }
    
    
        private static ByteArrayOutputStream get(Request request) throws HttpException {
            try {
                HttpURLConnection connection = (HttpURLConnection) new URL(request.url).openConnection();
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(15 * 1000);
                addHeaders(connection, request);
    
                if (HttpStatus.HTTP_OK == connection.getResponseCode()) {
                    InputStream is = connection.getInputStream();
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] buffer = new byte[2048];
                    int len = 0;
                    while (-1 != (len = is.read(buffer))) {
                        baos.write(buffer, 0, len);
                    }
                    baos.flush();
                    baos.close();
                    is.close();
                    return baos;
                }
            } catch (MalformedURLException e) {
                throw new HttpException(HttpException.Status.XXX_EXCEPTION);
            } catch (ProtocolException e) {
                throw new HttpException(HttpException.Status.XXX_EXCEPTION);
            } catch (SocketTimeoutException e) {
                throw new HttpException(HttpException.Status.TIMEOUT_EXCEPTION);
            } catch (IOException e) {
                throw new HttpException(HttpException.Status.XXX_EXCEPTION);
            }
            throw new HttpException(HttpException.Status.XXX_EXCEPTION);
        }
    
        private static ByteArrayOutputStream post(Request request) throws HttpException {
            try {
                HttpURLConnection connection = (HttpURLConnection) new URL(request.url).openConnection();
                connection.setRequestMethod("POST");
                connection.setConnectTimeout(15 * 1000);
                connection.setDoOutput(true);
                connection.setDoInput(true);
    
                addHeaders(connection, request);
    
                StringBuilder out = new StringBuilder();
                for (String key : request.body.keySet()) {
                    if (out.length() != 0) {
                        out.append("&");
                    }
                    out.append(key).append("=").append(request.body.get(key));
                }
                OutputStream outputStream = connection.getOutputStream();
                outputStream.write(out.toString().getBytes());
    
                if (HttpStatus.HTTP_OK == connection.getResponseCode()) {
                    InputStream is = connection.getInputStream();
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] buffer = new byte[2048];
                    int len = 0;
                    while (-1 != (len = is.read(buffer))) {
                        baos.write(buffer, 0, len);
                    }
                    baos.flush();
                    baos.close();
                    is.close();
                    return baos;
                }
            } catch (MalformedURLException e) {
                throw new HttpException(HttpException.Status.XXX_EXCEPTION);
            } catch (ProtocolException e) {
                throw new HttpException(HttpException.Status.XXX_EXCEPTION);
            } catch (SocketTimeoutException e) {
                throw new HttpException(HttpException.Status.TIMEOUT_EXCEPTION);
            } catch (IOException e) {
                throw new HttpException(HttpException.Status.XXX_EXCEPTION);
            }
            throw new HttpException(HttpException.Status.XXX_EXCEPTION);
        }
    
    
        private static void addHeaders(HttpURLConnection connection, Request request) {
            for (Map.Entry<String, String> header : request.headers.entrySet()) {
                connection.addRequestProperty(header.getKey(), header.getValue());
            }
        }
    
    
    }
    
    

    包装具体每一个请求的Request类

    public class Request {
        /**
         * 请求地址
         */
        public String url;
        /**
         * 请求form表单
         */
        public Map<String, String> body;
        /**
         * 请求头
         */
        public Map<String, String> headers = new HashMap<>();
        /**
         * 请求方法
         */
        public RequestMethod requestMethod;
        /**
         * 请求回调
         */
        public AbsCallback callBack;
    
        /**
         * 请求重试次数
         */
        public int maxRequestCount = 3;
    
        public enum RequestMethod {GET, POST}
    
        public Request(String url, RequestMethod requestMethod) {
            this.url = url;
            this.requestMethod = requestMethod;
        }
    
        public Request setUrl(String url) {
            this.url = url;
            return this;
        }
    
        public Request setBody(Map<String, String> body) {
            this.body = body;
            return this;
        }
    
        public void setCallBack(AbsCallback callBack) {
            this.callBack = callBack;
        }
    }
    
    

    基于Handler、ThreadPoolExecutor线程池的异步请求处理类

    public class RequestTask {
        private static final int MAIN_THREAD = 0x0001;
        private static InnerHandler handler = new InnerHandler();
    
        private final ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5,
                Integer.MAX_VALUE,
                60 * 1000,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingDeque<Runnable>(128));
        private Request request;
    
        public RequestTask(Request request) {
            this.request = request;
        }
    
        public void execute() {
            poolExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    Result result = request(0);
                    Message message = handler.obtainMessage();
                    message.obj = result;
                    message.what = MAIN_THREAD;
                    handler.sendMessage(message);
    
                }
            });
        }
    
        private Result request(int retry) {
            try {
                final ByteArrayOutputStream response = HttpUrlConnectionUtil.execute(request);
                return new Result(RequestTask.this, request.callBack.handleData(response));
            } catch (HttpException e) {
                if (e.type == HttpException.Status.TIMEOUT_EXCEPTION) {
                    if (retry < request.maxRequestCount) {
                        retry++;
                        request(retry);
                    }
                }
                return new Result(RequestTask.this, e);
            }
        }
    
    
        private static class InnerHandler extends Handler {
            private InnerHandler() {
                super(Looper.getMainLooper());
            }
    
            @Override
            public void handleMessage(Message msg) {
                Result result = (Result) msg.obj;
                switch (msg.what) {
                    case MAIN_THREAD:
                        if (result.response instanceof Exception) {
                            result.requestTask.request.callBack.failure((Exception) result.response);
                            return;
                        }
                        result.requestTask.request.callBack.sucess(result.response);
                }
            }
        }
    
        private static class Result<T> {
    
            private RequestTask requestTask;
            private T response;
    
            private Result(RequestTask requestTask, T response) {
                this.requestTask = requestTask;
                this.response = response;
            }
    
        }
    
    
    }
    

    可拓展的响应处理callback,自己可根据需要拓展

    public interface AbsCallback<T> {
        void sucess(T response);
        void failure(Exception e);
        T handleData(ByteArrayOutputStream response) throws HttpException;
    }
    
    public abstract class JsonCallback<T> implements AbsCallback<T> {
    
        private static Gson gson = new Gson();
    
        @Override
        @SuppressWarnings("unchecked")
        public T handleData(ByteArrayOutputStream response) throws HttpException {
            try {
                Class<T> clz= (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
                return gson.fromJson(response.toString("UTF-8"),clz);
            } catch (UnsupportedEncodingException e) {
                throw new HttpException(HttpException.Status.XXX_EXCEPTION);
            }
        }
    
    }
    
    public abstract class StringCallback implements AbsCallback<String> {
    
        @Override
        public String handleData(ByteArrayOutputStream response) throws HttpException {
            try {
                return response.toString("UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new HttpException(HttpException.Status.XXX_EXCEPTION);
            }
        }
    }
    

    有问题,请留言交流

    相关文章

      网友评论

        本文标题:手写HTTP网络请求框架

        本文链接:https://www.haomeiwen.com/subject/yqaqkqtx.html