Java 基础教程

Java 面向对象

Java 高级教程

Java 笔记

Java http 请求的几种方式详解


Java 进行 http 协议的请求主要有三种方式,一是 jdk 1.1 开始自带的 HttpURLConnection 及相关类,二是 apache commons 系列中的 httpclient 工具包,三是 square 公司开源的 OkHttp 工具包。

HttpURLConnection

HttpURLConnection 是 jdk 1.1 开始就加入的 http 工具类,它是一个抽象类,只能通过 url.openConnection() 方法创建具体的实例。严格来说,openConnection() 方法返回的是 URLConnection 的子类。只有 http 或 https 开头的 url 才返回 HttpURLConnection 对象。

GET 请求

HttpURLConnection get 请求示例:

    public static String doHttpGet(String httpUrlStr) {

        try {
            URL url = new URL(httpUrlStr);

            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();

            System.out.println("Connection impl class : " + httpConn.getClass());

            /**
             * 设置请求属性
             */
            //  设置请求方式为 GET,默认是 GET,可以不用设置
            httpConn.setRequestMethod("GET");

            //  设置连接超时时间,单位为毫秒
            httpConn.setConnectTimeout(5000);

            //  设置读取超时时间,单位为毫秒
            httpConn.setReadTimeout(4000);

            //  设置长连接,但是这个需要 http 1.1 协议及服务端支持才会真正生效
            httpConn.setRequestProperty("Connection", "Keep-Alive");

            StringBuilder response = new StringBuilder();

            String inputLine;
            BufferedReader br = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
            while ((inputLine = br.readLine()) != null) {
                response.append(inputLine);
            }
            br.close();

            String responseStr = response.toString();

            System.out.println("Sending Request to URL : " + httpUrlStr + "\n");

            int responseCode = httpConn.getResponseCode();
            System.out.println("Response Code : " + responseCode + "\n");

            String responseMessage = httpConn.getResponseMessage();
            System.out.println("Response Message : " + responseMessage + "\n");

            //  打印结果
            System.out.println("Response Content : " + responseStr);

            return responseStr;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return null;

    }

POST 请求

HttpURLConnection post 请求不同于 get 请求,需要额外设置一些属性,具体示例如下:

    public static String doHttpPost(String httpUrlStr, String jsonStr) {

        try {
            URL url = new URL(httpUrlStr);

            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();

            System.out.println("Connection impl class : " + httpConn.getClass());

            /**
             * 设置请求属性
             */
            //  设置请求方式为 POST
            httpConn.setRequestMethod("POST");

            //  设置请求数据格式,如 json 形式
            httpConn.setRequestProperty("Content-Type", "application/json; utf-8");

            //  设置接收数据格式,如 json 形式
            httpConn.setRequestProperty("Accept", "application/json");

            //  对于 post 请求,参数要放在 http 正文内,因此需要设为 true
            httpConn.setDoOutput(true);

            //  设置连接超时时间,单位为毫秒
            httpConn.setConnectTimeout(5000);

            //  设置读取超时时间,单位为毫秒
            httpConn.setReadTimeout(4000);

            //  设置长连接,但是这个需要 http 1.1 协议及服务端支持才会真正生效
            httpConn.setRequestProperty("Connection", "Keep-Alive");

            /**
             * 设置 post 请求体
             */
            if (jsonStr != null) {
                OutputStream os = httpConn.getOutputStream();
                byte[] input = jsonStr.getBytes("utf-8");
                os.write(input, 0, input.length);
                os.flush();
                os.close();
            }

            StringBuilder response = new StringBuilder();

            String inputLine;
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(httpConn.getInputStream(), "utf-8")
            );
            while ((inputLine = br.readLine()) != null) {
                response.append(inputLine);
            }
            br.close();

            String responseStr = response.toString();

            System.out.println("Sending Request to URL : " + httpUrlStr + "\n");

            int responseCode = httpConn.getResponseCode();
            System.out.println("Response Code : " + responseCode + "\n");

            String responseMessage = httpConn.getResponseMessage();
            System.out.println("Response Message : " + responseMessage + "\n");

            //  打印结果
            System.out.println("Response Content : " + responseStr);

            return responseStr;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return null;

    }

看到如上示例,读者可能会有疑问,真正的 http 请求是在哪个步骤触发的?其实,getOutputStream 和 getInputStream 内部都会隐式的调用 connect(),但是个人建议最好还是显性调用 connect() 方法,从源码可以看出,若多次调用 connect 方法,后面会自动忽略