简单描述一下我的应用场景,我们有两个项目分别部署在不同的服务器上,然后a项目中的某个功能需要调用b项目的接口去完成一些数据的同步和查询,并且b项目中还要做到一个ip的白名单限制,只有规定的ip才能访问,所以需要在a项目中编写一个远程访问类,下面就采用了URLConnection和HttpURLConnection分别封装了一个工具类

另外,这两个抽象类的区别我这里做了一个简单的记录,如果想要更清晰一些的讲解可以参考这位大神的帖子

1.URLConnection:抽象类 URLConnection 是所有类的超类,它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源。URLConnection 基于Http协议

package com.xxx.xxx.common.utils;


import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;

@Slf4j
public class HttpUtils {

    /**
     * GET请求
     * @param url 请求URL 参数用?和&拼接好在入参
     * @return
     */
    public static String get(String url) {
        String result = "";
        InputStream in = null;
        try {
            //1.通过在 URL 上调用 openConnection 方法创建连接对象
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            //2.处理设置参数和一般请求属性
            //2.1设置参数
            //可以根据请求的需要设置参数
            conn.setUseCaches(false);
            conn.setConnectTimeout(5000); //请求超时时间
            //2.2设置通用的请求属性,更多的头字段信息可以查阅HTTP协议
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            //3.使用 connect 方法建立到远程对象的实际连接。
            conn.connect();
            //获取URLConnection对象对应的输入流
            in = conn.getInputStream();
            //解析对方服务器返回的数据
            result = readInputStream(in);
            //关闭流
            in.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
            }
        }
        log.info("result=----" + result);
        return result;
    }

    /**
     * POST请求
     * @param url 请求URL
     * @param param 请求参数,请求参数格式 name1=value1&name2=value2(也可已同get方法一样直接拼接号url,params直接如" ")
     * @return
     */
    public static String post(String url, String param) {
        PrintWriter out = null;
        InputStream in = null;
        String result = "";
        try {
            //1.通过在 URL 上调用 openConnection 方法创建连接对象
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();

            //2.处理设置参数和一般请求属性
            //2.1发送POST请求必须设置如下两行 setDoOutput 和 setDoInput
            conn.setDoOutput(true);//默认为false 发送post请求必须设置setDoOutput(true)
            conn.setDoInput(true);//默认为true 所以不设置也可以
            conn.setUseCaches(false); //是否可以使用缓存 不使用缓存
            //2.2设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            //2.3设置请求正文 即要提交的数据
            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();

            //获取URLConnection对象对应的输入流
            in = conn.getInputStream();
            //解析对方服务器返回的数据
            result = readInputStream(in);

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                try {
                    if (out != null) {
                        out.close();
                    }
                } finally {
                    if (in != null) {
                        in.close();
                    }
                }
            } catch (Exception ex) {

            }
        }
        return result;
    }

    //解析对方服务器返回流
    public static String readInputStream(InputStream in) throws IOException {
        byte[] b=new byte[1024];
        StringBuffer sb1=new StringBuffer();
        int length=0;
        while ((length=in.read(b))!=-1){
            String s=new String(b, 0,length);
            sb1.append(s);
        }
        return sb1.toString();
    }

    public static void main(String[] args) {
        //远程连接请求数据
        String data = HttpUtils.get("http://x.x.x.x:7788/xxx/xxx/xxx?xxx=123456798.....");
        String data1 = HttpUtils.post("http://x.x.x.x:7788/xxx/xxx/xxx","xxx=123456789...");
        String data2 = HttpUtils.post("http://x.x.x.x:7788/xxx/xxx/xxx?xxx=123456798...","");
        System.out.println("get="+data);
        System.out.println("post="+data1);
        System.out.println("post="+data2);
    }
}

2.HttpURLConnection:支持 HTTP 特定功能的 URLConnection。每个 HttpURLConnection 实例都可用于生成单个请求,但是其他实例可以透明地共享连接到 HTTP 服务器的基础网络。请求后在 HttpURLConnection 的 InputStream 或 OutputStream 上调用 close() 方法可以释放与此实例关联的网络资源,但对共享的持久连接没有任何影响。如果在调用 disconnect() 时持久连接空闲,则可能关闭基础套接字,HttpURLConnection继承自URLConnection,相比较URLConnection类多了以下方法。 
- getResponseCode 从 HTTP 响应消息获取状态码。 
- getResponseMessage 获取与来自服务器的响应代码一起返回的 HTTP 响应消息(如果有)。

package com.xxx.xxx.common.utils;


import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.List;
import java.util.Map;

public class HttpUtils2 {

    /**
     * GET请求
     * @param geturl 请求URL  参数用?和&拼接好在入参
     * @return
     */
    public static String doGet(String geturl) {

        try {
            //1.通过在 URL 上调用 openConnection 方法创建连接对象
            URL url=new URL(geturl);
            //此处的urlConnection对象实际上是根据URL的请求协议(此处是http)生成的URLConnection类的子类HttpURLConnection,
            //故此处最好将其转化为HttpURLConnection类型的对象
            HttpURLConnection conn=(HttpURLConnection) url.openConnection();

            //2.处理设置参数和一般请求属性
            //2.1设置参数
            //可以根据请求的需要设置参数
            conn.setRequestMethod("GET"); //默认为GET 所以GET不设置也行
            conn.setUseCaches(false);
            conn.setConnectTimeout(5000); //请求超时时间

            //2.2请求属性
            //设置通用的请求属性 更多的头字段信息可以查阅HTTP协议
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");

            //3.使用 connect 方法建立到远程对象的实际连接。
            conn.connect();
            //获取URLConnection对象对应的输入流
            InputStream in = conn.getInputStream();
            //4.远程对象变为可用。远程对象的头字段和内容变为可访问。
            //4.1获取HTTP 响应消息获取状态码
            if(conn.getResponseCode()==200){//一般200都是请求成功,这里根据自己的实际业务来处理
                //4.2获取响应的头字段
                Map<String, List<String>> headers=conn.getHeaderFields();
                System.out.println(headers); //输出头字段

                //4.3获取响应正文
                //解析对方服务器返回的数据
               String result = readInputStream(in);
               return result;
            }
            //关闭流
            in.close();
            //断开连接,最好写上,disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
            //固定多线程的话,如果不disconnect,链接会增多,直到收发不出信息。写上disconnect后正常一些。
            conn.disconnect();//只有httpURLConnection中有,URLConnection 是没有的
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * POST请求
     * @param posturl 请求URL
     * @param params 请求参数,请求参数格式 name1=value1&name2=value2 (也可已同get方法一样直接拼接号url,params直接如" ")
     * @return
     */
    public static String doPost(String posturl,String params) {

        try {
            //1.通过在 URL 上调用 openConnection 方法创建连接对象
            URL url=new URL(posturl);
            HttpURLConnection conn=(HttpURLConnection) url.openConnection();

            //2.处理设置参数和一般请求属性
            //2.1设置参数,发送POST请求必须设置如下两行 setDoOutput 和 setDoInput
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);//默认为false 发送post请求必须设置setDoOutput(true)
            conn.setDoInput(true);//默认为true 所以不设置也可以
            conn.setUseCaches(false); //是否可以使用缓存 不使用缓存
            conn.setConnectTimeout(5000);//请求超时时间

            //2.2请求属性
            //设置通用的请求属性 消息报头 即设置头字段 更多的头字段信息可以查阅HTTP协议
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");

            //2.3设置请求正文 即要提交的数据
            PrintWriter pw=new PrintWriter(new OutputStreamWriter(conn.getOutputStream()));
            pw.print(params);
            pw.flush();
            pw.close();

            //3.使用 connect 方法建立到远程对象的实际连接。
            conn.connect();
            InputStream in=conn.getInputStream();
            //4.远程对象变为可用。远程对象的头字段和内容变为可访问。
            //4.1获取HTTP 响应消息获取状态码
            if(conn.getResponseCode()==200)
            {
                //4.2获取响应的头字段
                Map<String, List<String>> headers=conn.getHeaderFields();
                System.out.println(headers); //输出头字段

                //4.3获取响应正文
                //解析对方服务器返回的数据
                String result = readInputStream(in);
                return result;
            }
            in.close();
            //断开连接,最好写上,disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
            //固定多线程的话,如果不disconnect,链接会增多,直到收发不出信息。写上disconnect后正常一些。
            conn.disconnect();//只有httpURLConnection中有,URLConnection 是没有的
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    //解析对方服务器返回流
    public static String readInputStream(InputStream in) throws IOException {
        byte[] b=new byte[1024];
        StringBuffer sb1=new StringBuffer();
        int length=0;
        while ((length=in.read(b))!=-1){
            String s=new String(b, 0,length);
            sb1.append(s);
        }
        return sb1.toString();
    }

    public static void main(String[] args) {
        //远程连接请求数据
        String data = HttpUtils2.doGet("http://192.168.1.39:7788/xxx/xxx/xxx?xxx=123456798...");
        String data1 = HttpUtils2.doPost("http://192.168.1.39:7788/xxx/xxx/xxx","xxx=12345679...");
        String data2 = HttpUtils2.doPost("http://192.168.1.39:7788/xxx/xxx/xxx?xxx=123456798...","");
        System.out.println("get="+data);
        System.out.println("post="+data1);
        System.out.println("post="+data2);
    }
}