Android HttpURLConnection的使用

Posted 2015xbx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android HttpURLConnection的使用相关的知识,希望对你有一定的参考价值。

封装了get post form表单上传文件

public class FetchUrl {

    public static final class FetchUrlException extends Exception {
        private static final long serialVersionUID = -1225796193361530073L;
        private int mCode;
        private String mOrigMsg;

        public static final class CODE {
            public static final int UNSUPPORTED_PARAM_ENCODING = 1;
            public static final int SERVER_ERROR = 2;
            public static final int SERVER_READ_ERROR = 3;
            public static final int CLIENT_PROTOCOL_ERROR = 4;
            public static final int REQUEST_METHOD_NOT_ALLOWED = 5;
            public static final int NO_PEER_CERTIFICATE = 6;
            public static final int INVALID_URL = 7;
            public static final int ILLEGAL_PARAM = 9;
        }

        public FetchUrlException(int code, String origMsg) {
            super("Error Code: " + code);
            mCode = code;
            mOrigMsg = origMsg;
        }

        public int getCode() {
            return mCode;
        }

        public String getMsg() {
            switch (mCode) {
            case CODE.UNSUPPORTED_PARAM_ENCODING:
                return "Unsupported parameter encoding: " + mOrigMsg;
            case CODE.SERVER_ERROR:
                return "Server error: " + mOrigMsg;
            case CODE.SERVER_READ_ERROR:
                return "Server read error: " + mOrigMsg;
            case CODE.CLIENT_PROTOCOL_ERROR:
                return "Client protocol error: " + mOrigMsg;
            case CODE.REQUEST_METHOD_NOT_ALLOWED:
                return "Request method not allowed: " + mOrigMsg;
            case CODE.NO_PEER_CERTIFICATE:
                return "No peer certificate: " + mOrigMsg;
            case CODE.ILLEGAL_PARAM:
                return "Illegal paramters" + mOrigMsg;
            default:
                return "Unknown error: " + mOrigMsg;
            }
        }
    }

    public static final class FetchUrlMethod {
        public static final int GET = 0;
        public static final int POST = 1;
    }

    public static final class FetchUrlResponse {
        public int code;
        public byte[] content;
        public HashMap<String, String> headers;
        public List<String> cookies;
        public HashMap<String, String> cookie_maps;
    }

    protected static final String HEADER_ACCEPT_CHARSET = "Accept-Charset";
    protected static final String DEFAULT_PARAMS_ENCODING = "UTF-8";
    protected static final String POST_STR = "POST";
    protected static final String GET_STR = "GET";
    protected static final String BOUNDARY = "*****";
    protected static final String LINE_FEED = "\r\n";

    public static FetchUrlResponse fetchUrl(int method, String url, HashMap<String, String> headers,
            ArrayList<NameValuePair> data, int connection_timeout, int socket_timeout) throws FetchUrlException {
        return fetchUrl(method, url, headers, data, null, null, connection_timeout, socket_timeout);
    }

    public static FetchUrlResponse fetchUrl(int method, String url, HashMap<String, String> headers,
            ArrayList<NameValuePair> data, ArrayList<NameValuePair> form, Attatchment file, int connection_timeout,
            int socket_timeout) throws FetchUrlException {
        byte[] post_data = null;
        if (method == FetchUrlMethod.POST) {
            if (data != null && data.size() > 0) {
                try {
                    post_data = encodeParameters(data, DEFAULT_PARAMS_ENCODING);
                } catch (UnsupportedEncodingException e) {
                    throw new FetchUrlException(FetchUrlException.CODE.UNSUPPORTED_PARAM_ENCODING, e.getMessage());
                }
            }
        } else if (method == FetchUrlMethod.GET) {
            if (data != null && data.size() > 0) {
                if (url.contains("?")) {
                    throw new FetchUrlException(FetchUrlException.CODE.CLIENT_PROTOCOL_ERROR,
                            "data and query string are exclusive in GET method");
                }
                url = url + "?" + Utils.encodeQs(data);
            }
        } else {
            throw new FetchUrlException(FetchUrlException.CODE.REQUEST_METHOD_NOT_ALLOWED,
                    "" + method + " is not a valid request method");
        }
        return fetchUrlRaw(method, url, headers, post_data, form, file, connection_timeout, socket_timeout);
    }

    private static FetchUrlResponse fetchUrlRaw(int method, String url, HashMap<String, String> headers, byte[] data,
            ArrayList<NameValuePair> form, Attatchment file, int connection_timeout, int socket_timeout)
                    throws FetchUrlException {
        try {
            HttpURLConnection connection = openConnection(url, connection_timeout, socket_timeout);
            if (FetchUrlMethod.GET == method) {
                connection.setRequestMethod(GET_STR);
            } else if (FetchUrlMethod.POST == method) {
                connection.setRequestMethod(POST_STR);
            }

            if (file != null) {
                connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
            }

            if (headers != null && headers.size() > 0) {
                for (String headerName : headers.keySet()) {
                    connection.addRequestProperty(headerName, headers.get(headerName));
                }
            }

            DataOutputStream out = null;
            if (data != null) {
                connection.setDoOutput(true);
                out = new DataOutputStream(connection.getOutputStream());
                out.write(data);
                out.flush();
            }
            if (file != null) {
                if (out == null) {
                    connection.setDoOutput(true);
                    out = new DataOutputStream(connection.getOutputStream());
                }
                if (form != null && form.size() > 0) {
                    for (NameValuePair pair : form) {
                        StringBuilder sb = new StringBuilder();
                        sb.append("--" + BOUNDARY).append(LINE_FEED);
                        sb.append("Content-Disposition: form-data; name=\"" + pair.getName() + "\"").append(LINE_FEED);
                        sb.append("Content-Type: text/plain; charset=" + DEFAULT_PARAMS_ENCODING).append(LINE_FEED);
                        sb.append(LINE_FEED);
                        sb.append(pair.getValue()).append(LINE_FEED);
                        out.write(sb.toString().getBytes(DEFAULT_PARAMS_ENCODING));
                    }
                }
                StringBuilder sb = new StringBuilder();
                sb.append("--" + BOUNDARY).append(LINE_FEED);
                sb.append("Content-Disposition: form-data; name=\"" + file.name + "\"; filename=\"" + file.fileName
                        + "\"").append(LINE_FEED);
                sb.append("Content-Type: " + file.contentType).append(LINE_FEED);
                sb.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
                sb.append(LINE_FEED);
                out.write(sb.toString().getBytes(DEFAULT_PARAMS_ENCODING));

                byte[] buffer = new byte[4096];
                int bytesRead = -1;
                while ((bytesRead = file.inputStream.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }
                file.inputStream.close();
                out.write(LINE_FEED.getBytes(DEFAULT_PARAMS_ENCODING));

                String end = "--" + BOUNDARY + LINE_FEED;
                out.write(end.getBytes(DEFAULT_PARAMS_ENCODING));
                out.flush();
                out.close();
            } else if (form != null && form.size() > 0){
                for (NameValuePair pair : form) {
                    StringBuilder sb = new StringBuilder();
                    sb.append("--" + BOUNDARY).append(LINE_FEED);
                    sb.append("Content-Disposition: form-data; name=\"" + pair.getName() + "\"").append(LINE_FEED);
                    sb.append("Content-Type: text/plain; charset=" + DEFAULT_PARAMS_ENCODING).append(LINE_FEED);
                    sb.append(LINE_FEED);
                    sb.append(pair.getValue()).append(LINE_FEED);
                    out.write(sb.toString().getBytes(DEFAULT_PARAMS_ENCODING));
                }
                out.flush();
                out.close();
            }
            if (out != null) {
                out.close();
            }

            FetchUrlResponse response = new FetchUrlResponse();
            response.code = connection.getResponseCode();
            
            
            if (response.code == -1) {
                // -1 is returned by getResponseCode() if the response code
                // could not be retrieved.
                // Signal to the caller that something was wrong with the
                // connection.
                throw new IOException("Could not retrieve response code from HttpUrlConnection.");
            }
            InputStream istream;
            try {
                istream = connection.getInputStream();
            } catch (IOException e) {
                istream = connection.getErrorStream();
            }
            if (istream != null) {
                response.content = Utils.inputStreamToByteArray(istream);
            }
            response.headers = new HashMap<String, String>();
            Map<String, List<String>> respHeaders = connection.getHeaderFields();
            response.cookies = respHeaders.get("Set-Cookie");
            
            response.cookie_maps = new HashMap<String, String>();
            if (response.cookies != null) {
                for (String str : response.cookies) {
                    HttpCookie cookie = HttpCookie.parse(str).get(0);
                    response.cookie_maps.put(cookie.getName(), cookie.getValue());
                }
            }
            
            for (Map.Entry<String, List<String>> respHeader : respHeaders.entrySet()) {
                response.headers.put(respHeader.getKey(), connection.getHeaderField(respHeader.getKey()));
            }
            return response;

        } catch (SSLException e) {
            throw new FetchUrlException(FetchUrlException.CODE.NO_PEER_CERTIFICATE, e.getMessage());
        } catch (UnsupportedEncodingException e) {
            throw new FetchUrlException(FetchUrlException.CODE.UNSUPPORTED_PARAM_ENCODING, e.getMessage());
        } catch (ProtocolException e) {
            throw new FetchUrlException(FetchUrlException.CODE.CLIENT_PROTOCOL_ERROR, e.getMessage());
        } catch (IllegalAccessError e) {
            throw new FetchUrlException(FetchUrlException.CODE.SERVER_READ_ERROR, e.getMessage());
        } catch (NullPointerException e) {
            throw new FetchUrlException(FetchUrlException.CODE.ILLEGAL_PARAM, e.getMessage());
        } catch (IOException e) {
            throw new FetchUrlException(FetchUrlException.CODE.SERVER_READ_ERROR, e.getMessage());
        } catch (IllegalStateException e) {
            throw new FetchUrlException(FetchUrlException.CODE.SERVER_ERROR, e.getMessage());
        }
    }

    private static HttpURLConnection openConnection(String url, int connection_timeout, int socket_timeout)
            throws IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setRequestProperty(HEADER_ACCEPT_CHARSET, DEFAULT_PARAMS_ENCODING);
        connection.setConnectTimeout(connection_timeout);
        connection.setReadTimeout(socket_timeout);
        connection.setUseCaches(false);
        connection.setDoInput(true);
        return connection;
    }

    /**
     * Converts <code>params</code> into an application/x-www-form-urlencoded
     * encoded string.
     */
    private static byte[] encodeParameters(ArrayList<NameValuePair> params, String paramsEncoding)
            throws UnsupportedEncodingException {
        return Utils.encodeQs(params, paramsEncoding).getBytes(paramsEncoding);
    }

    public static String encodeQs(ArrayList<NameValuePair> data) {
        return Utils.encodeQs(data);
    }
}

 

public class Utils {
    public static String encodeQs(ArrayList<NameValuePair> data) {
        try {
            return encodeQs(data, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return null;
        }
    }

    static String encodeQs(ArrayList<NameValuePair> data, String paramsEncoding) throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.size(); i++) {
            NameValuePair kv = data.get(i);
            if (i != 0) {
                sb.append("&");
            }
            sb.append(URLEncoder.encode(kv.getName(), paramsEncoding));
            sb.append("=");
            sb.append(URLEncoder.encode(kv.getValue() == null ? "" : kv.getValue(), paramsEncoding));
        }
        return sb.toString();
    }

    static byte[] inputStreamToByteArray(InputStream is) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int read_count;
        byte[] data = new byte[16384];
        while ((read_count = is.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, read_count);
        }
        buffer.flush();
        return buffer.toByteArray();
    }

    // TODO always correct?
    public static String getLocalIpAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                        return inetAddress.getHostAddress();
                    }
                }
            }
        } catch (SocketException ex) {

        }
        return null;
    }

}

 

以上是关于Android HttpURLConnection的使用的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Android 的 HttpUrlConnection 不支持 HTTP/2?

Android中的HttpURLConnection有线记录

[Android基础]Android中使用HttpURLConnection

Android HttpUrlConnection 无法正常工作

HttpUrlConnection.getInputStream 在 Android 中返回空流

android中的HttpUrlConnection的使用之二