Java 基础教程

Java 面向对象

Java 高级教程

Java 笔记

Java FAQ

original icon
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.knowledgedict.com/tutorial/java-http.html

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 方法,后面会自动忽略