前言

本文中的内容其实严格来说不算springboot里面的特性,属于JAVA基础,只是我在项目中遇到了,特归纳总结一下。

HTTP请求封装

目前JAVA对于HTTP封装主要有三种方式:

  1. JAVA原生封装

  2. HttpClient 3.X /HttpClient4.X 

  3. Spring RestTemplate

http请求过程如下:

GET:
1、创建远程连接
2、设置连接方式(get、post、put。。。)
3、设置连接超时时间
4、设置响应读取时间
5、发起请求
6、获取请求数据
7、关闭连接

POST:
1、创建远程连接
2、设置连接方式(get、post、put。。。)
3、设置连接超时时间
4、设置响应读取时间
5、当向远程服务器传送数据/写数据时,需要设置为true(setDoOutput)
6、当前向远程服务读取数据时,设置为true,该参数可有可无(setDoInput)
7、设置传入参数的格式:(setRequestProperty)
8、设置鉴权信息:Authorization:(setRequestProperty)
9、设置参数
10、发起请求
11、获取请求数据
12、关闭连接

JAVA原生:

/** 
* http get请求
* @param httpUrl 链接
* @return 响应数据
*/
public
static String doGet(String httpUrl){ //链接 HttpURLConnection connection=null; InputStream is=null; BufferedReader br = null; StringBuffer result=new StringBuffer(); try { //创建连接 URL url=new URL(httpUrl); connection= (HttpURLConnection) url.openConnection(); //设置请求方式 connection.setRequestMethod("GET"); //设置连接超时时间 connection.setConnectTimeout(15000); //设置读取超时时间 connection.setReadTimeout(15000); //开始连接 connection.connect(); //获取响应数据 if(connection.getResponseCode()==200){ //获取返回的数据 is=connection.getInputStream(); if(is!=null){ br=new BufferedReader(new InputStreamReader(is,"UTF-8")); String temp = null; while ((temp=br.readLine())!=null){ result.append(temp); } } } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if(br!=null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if(is!=null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } connection.disconnect();// 关闭远程连接 } return result.toString(); } /** * post请求 * @param httpUrl 链接 * @param param 参数 * @return */ public static String doPost(String httpUrl, @Nullable String param) { StringBuffer result=new StringBuffer(); //连接 HttpURLConnection connection=null; OutputStream os=null; InputStream is=null; BufferedReader br=null; try { //创建连接对象 URL url=new URL(httpUrl); //创建连接 connection= (HttpURLConnection) url.openConnection(); //设置请求方法 connection.setRequestMethod("POST"); //设置连接超时时间 connection.setConnectTimeout(15000); //设置读取超时时间 connection.setReadTimeout(15000); //设置是否可读取 connection.setDoOutput(true); //设置响应是否可读取 connection.setDoInput(true); //设置参数类型 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); //拼装参数 if(param!=null&&!param.equals("")){ //设置参数 os=connection.getOutputStream(); //拼装参数 os.write(param.getBytes("UTF-8")); } //设置权限 //设置请求头等 //开启连接 //connection.connect(); //读取响应 if(connection.getResponseCode()==200){ is=connection.getInputStream(); if(is!=null){ br=new BufferedReader(new InputStreamReader(is,"UTF-8")); String temp=null; if((temp=br.readLine())!=null){ result.append(temp); } } } //关闭连接 } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if(br!=null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if(os!=null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if(is!=null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } //关闭连接 connection.disconnect(); } return result.toString(); }

HttpCLient4.X 

httpclient有很多版本,目前最新的版本是4.X了,所以推荐使用4.x的方式进行封装

public static String doGet(String url) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        String result = "";
        try {
            // 通过址默认配置创建一个httpClient实例
            httpClient = HttpClients.createDefault();
            // 创建httpGet远程连接实例
            HttpGet httpGet = new HttpGet(url);
            // 设置请求头信息,鉴权
            httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
            // 设置配置请求参数
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
                    .setConnectionRequestTimeout(35000)// 请求超时时间
                    .setSocketTimeout(60000)// 数据读取超时时间
                    .build();
            // 为httpGet实例设置配置
            httpGet.setConfig(requestConfig);
            // 执行get请求得到返回对象
            response = httpClient.execute(httpGet);
            // 通过返回对象获取返回数据
            HttpEntity entity = response.getEntity();
            // 通过EntityUtils中的toString方法将结果转换为字符串
            result = EntityUtils.toString(entity);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != response) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public static String doPost(String url, Map<String, Object> paramMap) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        String result = "";
        // 创建httpClient实例
        httpClient = HttpClients.createDefault();
        // 创建httpPost远程连接实例
        HttpPost httpPost = new HttpPost(url);
        // 配置请求参数实例
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
                .setConnectionRequestTimeout(35000)// 设置连接请求超时时间
                .setSocketTimeout(60000)// 设置读取数据连接超时时间
                .build();
        // 为httpPost实例设置配置
        httpPost.setConfig(requestConfig);
        // 设置请求头
        httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
        // 封装post请求参数
        if (null != paramMap && paramMap.size() > 0) {
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            // 通过map集成entrySet方法获取entity
            Set<Entry<String, Object>> entrySet = paramMap.entrySet();
            // 循环遍历,获取迭代器
            Iterator<Entry<String, Object>> iterator = entrySet.iterator();
            while (iterator.hasNext()) {
                Entry<String, Object> mapEntry = iterator.next();
                nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
            }

            // 为httpPost设置封装好的请求参数
            try {
                httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        try {
            // httpClient对象执行post请求,并返回响应参数对象
            httpResponse = httpClient.execute(httpPost);
            // 从响应对象中获取响应内容
            HttpEntity entity = httpResponse.getEntity();
            result = EntityUtils.toString(entity);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != httpResponse) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

Spring RestTemplate 封装HTTP

spring自带的一种封装模式,方便简洁,推荐使用

public static String httpGet(String url){
        RestTemplate restTemplate=new RestTemplate();
        String result=restTemplate.exchange(url, HttpMethod.GET,null,String.class).getBody();
        return result;
    }

    public static String httpPost(String url,String name){
        RestTemplate restTemplate=new RestTemplate();
        return restTemplate.postForEntity(url,name,String.class).getBody();
    }

HTTPS请求的封装

https请求只是在http请求的基础上面添加了SSL验证,通过下面的SLLClient 封装即可,调用的时候:

public class SSLClient {
    public static CloseableHttpClient createSSLClientDefault(){
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                //信任所有
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return  HttpClients.createDefault();
    }

}

JSON多层嵌套

处理接口返回的时候,目前用的最多的方式是返回json格式,因为json格式比较成熟,包括取值,实例化等等。这里介绍一种后端处理json返回多层嵌套的方式:

优点: 实例化了数据结构,想获取任何数据都能使用实例化的方法。不用理会它有几层,它的数据结构是什么(List, array, string等等)

缺点: 需要返回的数据结构稳定,不能返回变动的数据结构, 另外实例化有一定的代码量,比较繁琐(但是有固定插件解决)

实操:

实例化截图:

Service层调用实例化:

    //实例化的时候注意数据格式,List的话可以循环获取(下面的注释部分);最终存储到map里面返回
     Gateway gatewaydata = JSON.parseObject(res, Gateway.class); Map<String,String> resMap=new HashMap<>(); String value=gatewaydata.getComponent().getMeasures().get(0).getPeriods().get(0).getValue(); String metric=gatewaydata.getComponent().getMeasures().get(0).getMetric(); //获取各个区的名称 // List<Country> clist=state.getData().get(0).getCity().get(0).getCounty(); // for(Country c:clist){ // System.out.println("cname:"+c.getName()); // } System.out.println(value+metric); resMap.put("metric",metric); resMap.put("value",value);
02-11 03:48