import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.io.PrintWriter;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;


/**
     * get请求获取数据
     */   
    public static String getJson(String httpUrl, String httpArg) {
        BufferedReader reader = null;
        String result = null;
        StringBuffer sbf = new StringBuffer();
        httpUrl = httpUrl + "?" + httpArg;

        try {
            URL url = new URL(httpUrl);
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();
            connection.setRequestMethod("GET");
            /**setRequestProperty(key,value)
             * Sets the general request property. If a property with the key already
             * exists, overwrite its value with the new value.
             *  设置通用的请求属性。如果该key对应的的属性值已经存在,那么新值将覆盖以前的值
             * <p> NOTE: HTTP requires all request properties which can
             * legally have multiple instances with the same key
             * to use a comma-seperated list syntax which enables multiple
             * properties to be appended into a single property.
             *提示:HTTP要求拥有相同key值的多个实例的所有请求属性,可以使用逗号分隔的列表语法,这样就可以将多个属性附加到单个属性中
             * @param   key     the keyword by which the request is known
             *                  (e.g., "<code>Accept</code>").
             * @param   value   the value associated with it.
             * @throws IllegalStateException if already connected
             * @throws NullPointerException if key is <CODE>null</CODE>
             * @see #getRequestProperty(java.lang.String)
             */
            connection.setRequestProperty("apikey",  "71e4b699*********cf44ebb02cd2");
            connection.connect();
            InputStream is = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead);
                sbf.append("\r\n");
            }
            reader.close();
            result = sbf.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
	
    /**
     * POST请求获取数据
     */
       public static String postDownloadJson(String path,String post){
        URL url = null;
        try {
            url = new URL(path);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setRequestMethod("POST");// 提交模式
            // conn.setConnectTimeout(10000);//连接超时 单位毫秒
            // conn.setReadTimeout(2000);//读取超时 单位毫秒
            // 发送POST请求必须设置如下两行 
            httpURLConnection.setDoOutput(true);//http正文内,因此需要设为true, 默认情况下是false; 
            httpURLConnection.setDoInput(true);// 设置是否从httpUrlConnection读入,默认情况下是true;
            // 获取URLConnection对象对应的输出流  此处getOutputStream会隐含的进行connect(即:如同调用上面的connect()方法, 
            PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
            // 发送请求参数
            printWriter.write(post);//post的参数 xx=xx&yy=yy
            // flush输出流的缓冲
            printWriter.flush();
            //开始获取数据 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端
            BufferedInputStream bis = new BufferedInputStream(httpURLConnection.getInputStream());//实际发送请求的代码段就在这里
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            int len;
            byte[] arr = new byte[1024];
            while((len=bis.read(arr))!= -1){
                bos.write(arr,0,len);
                bos.flush();
            }
            bos.close();
            return bos.toString("utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

 总结:a:) HttpURLConnection的connect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。 

    无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。 
       b:) 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重, 
    对connection对象的一切配置(那一堆set函数) 
    都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。 
    这些顺序实际上是由http请求的格式决定的。 
    如果inputStream读操作在outputStream的写操作之前,会抛出例外: 
    java.net.ProtocolException: Cannot write output after reading input....... 
       
       c:) http请求实际上由两部分组成, 
    一个是http头,所有关于此次http请求的配置都在http头里面定义, 
           一个是正文content。 
    connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前,     就必须把所有的配置准备好。 
       d:) 在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的, 
    实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,     而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。     至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求    正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http 请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数  之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)  都是没有意义的了,执行这些操作会导致异常的发生。