zoukankan      html  css  js  c++  java
  • Java调用第三方接口(http总结)

    业务需求:

    一般情况下都是 后端提供接口,前端调用,解决需求,但是有的时候为了方便,复用别人的接口(网上的,公共的第三方接口(短信、天气等)),就出现了后端调用后端接口的情况。(类似JavaScript中的ajax一样获取数据,并对数据进行处理)

    对比

    一般情况:

    前端调用后端接口

    业务情况:

    后端调用后端接口

    几种方式总结:

    在Java项目中调用第三方接口的方式有:

    ①通过JDK网络类Java.net.HttpURLConnection;

    ②通过common封装好的HttpClient;

    ③通过Apache封装好的CloseableHttpClient;

    ④通过SpringBoot-RestTemplate;

    1. 通过JDK网络类Java.net.HttpURLConnection

    比较原始的一种调用做法,这里把get请求和post请求都统一放在一个方法里面

    public class HttpUrlConnectionToInterface {
    
        /**
         * 以post或get方式调用对方接口方法,
         * @param pathUrl
         */
        public static void doPostOrGet(String pathUrl, String data){
            OutputStreamWriter out = null;
            BufferedReader br = null;
            String result = "";
            try {
                URL url = new URL(pathUrl);
                //打开和url之间的连接
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                //请求方式
                conn.setRequestMethod("POST");
                //conn.setRequestMethod("GET");
    
                //设置通用的请求属性
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
                conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
    
                //DoOutput设置是否向httpUrlConnection输出,DoInput设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个
                conn.setDoOutput(true);
                conn.setDoInput(true);
    
                /**
                 * 下面的三句代码,就是调用第三方http接口
                 */
                //获取URLConnection对象对应的输出流
                out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
                //发送请求参数即数据
                out.write(data);
                //flush输出流的缓冲
                out.flush();
    
                /**
                 * 下面的代码相当于,获取调用第三方http接口后返回的结果
                 */
                //获取URLConnection对象对应的输入流
                InputStream is = conn.getInputStream();
                //构造一个字符流缓存
                br = new BufferedReader(new InputStreamReader(is));
                String str = "";
                while ((str = br.readLine()) != null){
                    result += str;
                }
                System.out.println(result);
                //关闭流
                is.close();
                //断开连接,disconnect是在底层tcp socket链接空闲时才切断,如果正在被其他线程使用就不切断。
                conn.disconnect();
    
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    if (out != null){
                        out.close();
                    }
                    if (br != null){
                        br.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String[] args) {
            /**
             *手机信息查询接口:http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=手机号
         *      http://api.showji.com/Locating/www.showji.com.aspx?m=手机号&output=json&callback=querycallback
             */
            doPostOrGet("https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13026194071", "");
        }
    }
    
    2. 通过apache common封装好的HttpClient

    httpClient的get或post请求方式步骤:

    1. 生成一个HttpClient对象并设置相应的参数
    2. 生成一个GetMethod对象或PostMethod并设置响应的参数
    3. 用HttpClient生成的对象来执行GetMethod生成的Get方法
    4. 处理响应状态码
    5. 若响应正常,处理HTTP响应内容
    6. 释放连接

    pom文件添加依赖:

            <dependency>
                <groupId>commons-httpclient</groupId>
                <artifactId>commons-httpclient</artifactId>
                <version>3.1</version>
            </dependency>
    
    生活小提示:

    如果有一些jar包找不到,(不是maven管理需要自己下载)有时候有各种问题,或者墙或者找不到之类,可以通过创建一个maven空项目,添加pom依赖,然后下载,在pom仓库里找到即可用。

    public class HttpClientToInterface {
    
        /**
         * httpClient的get请求方式
         * 使用GetMethod来访问一个URL对应的网页实现步骤:
         * 1.生成一个HttpClient对象并设置相应的参数;
         * 2.生成一个GetMethod对象并设置响应的参数;
         * 3.用HttpClient生成的对象来执行GetMethod生成的Get方法;
         * 4.处理响应状态码;
         * 5.若响应正常,处理HTTP响应内容;
         * 6.释放连接。
         * @param url
         * @param charset
         * @return
         */
        public static String doGet(String url, String charset){
            /**
             * 1.生成HttpClient对象并设置参数
             */
            HttpClient httpClient = new HttpClient();
            //设置Http连接超时为5秒
            httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
    
            /**
             * 2.生成GetMethod对象并设置参数
             */
            GetMethod getMethod = new GetMethod(url);
            //设置get请求超时为5秒
            getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);
            //设置请求重试处理,用的是默认的重试处理:请求三次
            getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());
    
            String response = "";
    
            /**
             * 3.执行HTTP GET 请求
             */
            try {
                int statusCode = httpClient.executeMethod(getMethod);
    
                /**
                 * 4.判断访问的状态码
                 */
                if (statusCode != HttpStatus.SC_OK){
                    System.err.println("请求出错:" + getMethod.getStatusLine());
                }
    
                /**
                 * 5.处理HTTP响应内容
                 */
                //HTTP响应头部信息,这里简单打印
                Header[] headers = getMethod.getResponseHeaders();
                for (Header h: headers){
                    System.out.println(h.getName() + "---------------" + h.getValue());
                }
                //读取HTTP响应内容,这里简单打印网页内容
                //读取为字节数组
                byte[] responseBody = getMethod.getResponseBody();
                response = new String(responseBody, charset);
                System.out.println("-----------response:" + response);
                //读取为InputStream,在网页内容数据量大时候推荐使用
                //InputStream response = getMethod.getResponseBodyAsStream();
    
            } catch (HttpException e) {
                //发生致命的异常,可能是协议不对或者返回的内容有问题
                System.out.println("请检查输入的URL!");
                e.printStackTrace();
            } catch (IOException e){
                //发生网络异常
                System.out.println("发生网络异常!");
            }finally {
                /**
                 * 6.释放连接
                 */
                getMethod.releaseConnection();
            }
            return response;
        }
    
        /**
         * post请求
         * @param url
         * @param json
         * @return
         */
        public static String doPost(String url, JSONObject json){
            HttpClient httpClient = new HttpClient();
            PostMethod postMethod = new PostMethod(url);
    
            postMethod.addRequestHeader("accept", "*/*");
            postMethod.addRequestHeader("connection", "Keep-Alive");
            //设置json格式传送
            postMethod.addRequestHeader("Content-Type", "application/json;charset=utf-8");
            //必须设置下面这个Header
            postMethod.addRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
            //添加请求参数
            postMethod.addParameter("commentId", json.getString("commentId"));
    
            String res = "";
            try {
                int code = httpClient.executeMethod(postMethod);
                if (code == 200){
                    res = postMethod.getResponseBodyAsString();
                    System.out.println(res);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return res;
        }
    
        public static void main(String[] args) {
            doGet("http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13026194071", "UTF-8");
            System.out.println("-----------分割线------------");
            System.out.println("-----------分割线------------");
            System.out.println("-----------分割线------------");
    
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("commentId", "13026194071");
            doPost("http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13026194071", jsonObject);
        }
    }
    
    3 通过Apache封装好的CloseableHttpClient

    CloseableHttpClient是在HttpClient的基础上修改更新而来的,这里还涉及到请求头token的设置(请求验证),利用fastjson转换请求或返回结果字符串为json格式,当然上面两种方式也是可以设置请求头token、json的,这里只在下面说明。

     <!--CloseableHttpClient-->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.5.2</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.28</version>
            </dependency>
    
    public class CloseableHttpClientToInterface {
    
        private static String tokenString = "";
        private static String AUTH_TOKEN_EXPIRED = "AUTH_TOKEN_EXPIRED";
        private static CloseableHttpClient httpClient = null;
    
        /**
         * 以get方式调用第三方接口
         * @param url
         * @return
         */
        public static String doGet(String url, String token){
            //创建HttpClient对象
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            HttpGet get = new HttpGet(url);
    
            try {
                if (tokenString != null && !tokenString.equals("")){
                    tokenString = getToken();
                }
                //api_gateway_auth_token自定义header头,用于token验证使用
                get.addHeader("api_gateway_auth_token", tokenString);
                get.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
                HttpResponse response = httpClient.execute(get);
                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                    //返回json格式
                    String res = EntityUtils.toString(response.getEntity());
                    return res;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 以post方式调用第三方接口
         * @param url
         * @param json
         * @return
         */
        public static String doPost(String url, JSONObject json){
            
            try {
                if (httpClient == null){
                    httpClient = HttpClientBuilder.create().build();
                }
    
                HttpPost post = new HttpPost(url);
                
                if (tokenString != null && !tokenString.equals("")){
                    tokenString = getToken();
                }
                
                //api_gateway_auth_token自定义header头,用于token验证使用
                post.addHeader("api_gateway_auth_token", tokenString);
                post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
    
                StringEntity s = new StringEntity(json.toString());
                s.setContentEncoding("UTF-8");
                //发送json数据需要设置contentType
                s.setContentType("application/x-www-form-urlencoded");
                //设置请求参数
                post.setEntity(s);
                HttpResponse response = httpClient.execute(post);
    
                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
                    //返回json格式
                    String res = EntityUtils.toString(response.getEntity());
                    return res;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if (httpClient != null){
                    try {
                        httpClient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }
    
        /**
         * 获取第三方接口的token
         */
        public static String getToken(){
    
            String token = "";
    
            JSONObject object = new JSONObject();
            object.put("appid", "appid");
            object.put("secretkey", "secretkey");
    
            try {
                if (httpClient == null){
                    httpClient = HttpClientBuilder.create().build();
                }
                HttpPost post = new HttpPost("http://localhost/login");
                
                post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
    
                StringEntity s = new StringEntity(object.toString());
                s.setContentEncoding("UTF-8");
                //发送json数据需要设置contentType
                s.setContentType("application/x-www-form-urlencoded");
                //设置请求参数
                post.setEntity(s);
                HttpResponse response = httpClient.execute(post);
    
                //这里可以把返回的结果按照自定义的返回数据结果,把string转换成自定义类
                //ResultTokenBO result = JSONObject.parseObject(response, ResultTokenBO.class);
    
               //把response转为jsonObject
                JSONObject result = JSONObject.parseObject(response);
                if (result.containsKey("token")){
                    token = result.getString("token");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return token;
        }
    
        /**
         * 测试
         */
        public static void test(String telephone){
    
            JSONObject object = new JSONObject();
            object.put("telephone", telephone);
    
            try {
                //首先获取token
                tokenString = getToken();
                String response = doPost("http://localhost/searchUrl", object);
    
                //如果返回的结果是list形式的,需要使用JSONObject.parseArray转换
                //List<Result> list = JSONObject.parseArray(response, Result.class);
    
                System.out.println(response);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            test("12345678910");
        }
    
    }
    
    4 通过SpringBoot-RestTemplate

    springBoot-RestTemple是上面三种方式的集大成者,代码编写更加简单,目前可以采用的调用第三方接口有:

    delete() 在特定的URL上对资源执行HTTP DELETE操作
    exchange() 在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的
    execute() 在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象
    getForEntity() 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象
    getForObject() 发送一个HTTP GET请求,返回的请求体将映射为一个对象
    postForEntity() POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得到的
    postForObject() POST 数据到一个URL,返回根据响应体匹配形成的对象
    headForHeaders() 发送HTTP HEAD请求,返回包含特定资源URL的HTTP头
    optionsForAllow() 发送HTTP OPTIONS请求,返回对特定URL的Allow头信息
    postForLocation() POST 数据到一个URL,返回新创建资源的URL
    put() PUT 资源到特定的URL
    

    参考:
    http://www.cnblogs.com/angusbao/p/7727649.html 纯Java api HttpURLConnection

    https://blog.csdn.net/chijiandi/article/details/81388240 纯Java api HttpURLConnection

    https://www.cnblogs.com/xuegu/p/8490815.html 封装api HttpClient

    https://www.cnblogs.com/unknows/p/8534713.html

    https://blog.csdn.net/qq_35860138/article/details/82967727 封装api HttpClient

    https://www.cnblogs.com/swordfall/p/10757499.html

    https://blog.csdn.net/a1032818891/article/details/81172478 SpringBoot-RestTemplate

  • 相关阅读:
    Insus Meta Utility
    The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
    Insus Binary Utility
    asp.net实现文件下载功能
    Column 'Column Name' does not belong to table Table
    程序已被编译为DLL,怎样去修改程序功能
    如何在Web网站实现搜索功能
    如何把数据流转换为二进制字符串
    Asp.net更新文件夹的文件
    如何显示中文月份
  • 原文地址:https://www.cnblogs.com/biturd/p/12623178.html
Copyright © 2011-2022 走看看