JAVA - HttpClient Packaging Tools

In the daily development, we often need to call web content via http protocol, although net java itself provides tools package, but its flexibility and functionality are always unsatisfactory, so it was special to come up with a httpclient library to facilitate Http operation. Simple Simple operation httpcient package into a utility class, unified on the project toolkit, called directly from the kit when in use, do not need to write redundant code.

DEMO 1 

package club.zstuca.myzstu.httpclient;

import club.zstuca.myzstu.consts.Consts;
import org.apache.commons.collections4.MapUtils;
import org.apache.http.*;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Http/Https请求的工具类
 */
public class HttpClientUtils {
    private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);
    private static RequestConfig requestConfig=null;
    static{
        requestConfig = RequestConfig.custom().setConnectTimeout(5000)
                .setConnectionRequestTimeout(5000)
                .setSocketTimeout(5000)
                .setRedirectsEnabled(false).build();
    }
    /**
     * 发送post请求
     *
     * @param url 请求地址
     * @param header 请求头参数
     * @param params   json/xml参数
     * @return
     */
    public static String doPostRequest(String url, Map<String, String> header, Map<String, String> params) {
    	String resultStr = "";
        if (StringUtils.isEmpty(url)) {
            return resultStr;
        }
        logger.info(url);
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        try {
            httpClient = HTTPClientPool.getHttpClient();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            if (MapUtils.isEmpty(header)) {
                for (Map.Entry<String, String> headerEntry : header.entrySet()) {
                    httpPost.setHeader(headerEntry.getKey(), headerEntry.getValue());
                }
            }
            if (MapUtils.isEmpty(params)) {
                List<NameValuePair> paramspair=new ArrayList<>();
                for (Map.Entry<String, String> paramEntry:header.entrySet()) {
                    paramspair.add(new BasicNameValuePair(paramEntry.getKey(),paramEntry.getValue()));
                }
                httpPost.setEntity(new UrlEncodedFormEntity(paramspair, Consts.ENCODING));
            }
            httpResponse = httpClient.execute(httpPost);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                HttpEntity httpResponseEntity = httpResponse.getEntity();
                resultStr = EntityUtils.toString(httpResponseEntity, Consts.ENCODING);
                //logger.info("POST请求正常,请求地址:{},响应结果:{}", url, resultStr);
            } else {
                StringBuffer stringBuffer = new StringBuffer();
                HeaderIterator headerIterator = httpResponse.headerIterator();
                while (headerIterator.hasNext()) {
                    stringBuffer.append("\t" + headerIterator.next());
                }
                httpPost.abort();
                //logger.info("POST请求异常信息:请求地址:{},响应状态:{},请求返回结果:{}", url, httpResponse.getStatusLine().getStatusCode(),stringBuffer);
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            HttpClientUtils.closeConnection(httpClient, httpResponse);
        }
        return resultStr;
    }

    public static String doGetRequest(String url, Map<String, String> header, Map<String, String> params) {
    	String resultStr = "";
        if (StringUtils.isEmpty(url)) {
            return resultStr;
        }
        logger.info(url);
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        try {
            httpClient = HTTPClientPool.getHttpClient();
            URIBuilder urlbuilder = new URIBuilder(url);
            if (MapUtils.isNotEmpty(params)) {
                // Set GET params
                for (Map.Entry<String, String> stringStringEntry : params.entrySet()) {
                    urlbuilder.setParameter(stringStringEntry.getKey(), stringStringEntry.getValue());
                }
            }
            HttpGet httpGet = new HttpGet(urlbuilder.build());
            logger.info(urlbuilder.build().toURL().toString());
            httpGet.setConfig(requestConfig);
            if (MapUtils.isNotEmpty(header)) {
                for (Map.Entry<String, String> stringStringEntry : header.entrySet()) {
                    httpGet.setHeader(stringStringEntry.getKey(), stringStringEntry.getValue());
                }
            }
            //发起请求
            httpResponse = httpClient.execute(httpGet);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                resultStr = EntityUtils.toString(httpResponse.getEntity(), Consts.ENCODING);
                //logger.info("GET请求正常,请求地址:{},响应结果:{}", url,resultStr);
            } else {
                StringBuffer stringBuffer = new StringBuffer();
                HeaderIterator headerIterator = httpResponse.headerIterator();
                while (headerIterator.hasNext()) {
                    stringBuffer.append("\t" + headerIterator.next());
                }
                httpGet.abort();
                //logger.info("GET请求异常信息:请求响应状态:{},请求返回结果:{}", httpResponse.getStatusLine().getStatusCode(), stringBuffer);
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            HttpClientUtils.closeConnection(httpClient, httpResponse);
        }
        return resultStr;
    }

    /**
     * 关掉连接释放资源
     */
    private static void closeConnection(CloseableHttpClient httpClient, CloseableHttpResponse httpResponse) {
        if (httpClient != null) {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (httpResponse != null) {
            try {
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

DEMO 2

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;

/**
 * 基于 httpclient 4.5版本的 http工具类
 * 
 * @author 爱琴孩
 * 
 */
public class HttpClientTool {

	private static final CloseableHttpClient httpClient;
	public static final String CHARSET = "UTF-8";
	// 采用静态代码块,初始化超时时间配置,再根据配置生成默认httpClient对象
	static {
		RequestConfig config = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(15000).build();
		httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
	}

	public static String doGet(String url, Map<String, String> params) {
		return doGet(url, params, CHARSET);
	}

	public static String doGetSSL(String url, Map<String, String> params) {
		return doGetSSL(url, params, CHARSET);
	}

	public static String doPost(String url, Map<String, String> params) throws IOException {
		return doPost(url, params, CHARSET);
	}

	/**
	 * HTTP Get 获取内容
	 * @param url 请求的url地址 ?之前的地址
	 * @param params 请求的参数
	 * @param charset 编码格式
	 * @return 页面内容
	 */
	public static String doGet(String url, Map<String, String> params, String charset) {
		if (StringUtils.isBlank(url)) {
			return null;
		}
		try {
			if (params != null && !params.isEmpty()) {
				List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
				for (Map.Entry<String, String> entry : params.entrySet()) {
					String value = entry.getValue();
					if (value != null) {
						pairs.add(new BasicNameValuePair(entry.getKey(), value));
					}
				}
				// 将请求参数和url进行拼接
				url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
			}
			HttpGet httpGet = new HttpGet(url);
			CloseableHttpResponse response = httpClient.execute(httpGet);
			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != 200) {
				httpGet.abort();
				throw new RuntimeException("HttpClient,error status code :" + statusCode);
			}
			HttpEntity entity = response.getEntity();
			String result = null;
			if (entity != null) {
				result = EntityUtils.toString(entity, "utf-8");
			}
			EntityUtils.consume(entity);
			response.close();
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * HTTP Post 获取内容
	 * @param url 请求的url地址 ?之前的地址
	 * @param params 请求的参数
	 * @param charset 编码格式
	 * @return 页面内容
	 * @throws IOException
	 */
	public static String doPost(String url, Map<String, String> params, String charset) 
			throws IOException {
		if (StringUtils.isBlank(url)) {
			return null;
		}
		List<NameValuePair> pairs = null;
		if (params != null && !params.isEmpty()) {
			pairs = new ArrayList<NameValuePair>(params.size());
			for (Map.Entry<String, String> entry : params.entrySet()) {
				String value = entry.getValue();
				if (value != null) {
					pairs.add(new BasicNameValuePair(entry.getKey(), value));
				}
			}
		}
		HttpPost httpPost = new HttpPost(url);
		if (pairs != null && pairs.size() > 0) {
			httpPost.setEntity(new UrlEncodedFormEntity(pairs, CHARSET));
		}
		CloseableHttpResponse response = null;
		try {
			response = httpClient.execute(httpPost);
			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != 200) {
				httpPost.abort();
				throw new RuntimeException("HttpClient,error status code :" + statusCode);
			}
			HttpEntity entity = response.getEntity();
			String result = null;
			if (entity != null) {
				result = EntityUtils.toString(entity, "utf-8");
			}
			EntityUtils.consume(entity);
			return result;
		} catch (ParseException e) {
			e.printStackTrace();
		} finally {
			if (response != null)
				response.close();
		}
		return null;
	}

	/**
	 * HTTPS Get 获取内容
	 * @param url 请求的url地址 ?之前的地址
	 * @param params 请求的参数
	 * @param charset  编码格式
	 * @return 页面内容
	 */
	public static String doGetSSL(String url, Map<String, String> params, String charset) {
		if (StringUtils.isBlank(url)) {
			return null;
		}
		try {
			if (params != null && !params.isEmpty()) {
				List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
				for (Map.Entry<String, String> entry : params.entrySet()) {
					String value = entry.getValue();
					if (value != null) {
						pairs.add(new BasicNameValuePair(entry.getKey(), value));
					}
				}
				url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
			}
			HttpGet httpGet = new HttpGet(url);

			// https  注意这里获取https内容,使用了忽略证书的方式,当然还有其他的方式来获取https内容
			CloseableHttpClient httpsClient = HttpClientTool.createSSLClientDefault();
			CloseableHttpResponse response = httpsClient.execute(httpGet);
			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode != 200) {
				httpGet.abort();
				throw new RuntimeException("HttpClient,error status code :" + statusCode);
			}
			HttpEntity entity = response.getEntity();
			String result = null;
			if (entity != null) {
				result = EntityUtils.toString(entity, "utf-8");
			}
			EntityUtils.consume(entity);
			response.close();
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 这里创建了忽略整数验证的CloseableHttpClient对象
	 * @return
	 */
	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();
	}
}

DEMO 3

package zhihuisystem.HttpClient_Test;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

public class HttpClient_Utils {
    // 常规get请求
    public static String Getmethod(String url) {
        CloseableHttpClient client = HttpClientBuilder.create().build();
        HttpGet get = new HttpGet(url);
        CloseableHttpResponse respons1 = null;
        try {
            respons1 = client.execute(get);
        } catch (ClientProtocolException e1) {
            System.out.println("客户端get请求异常");
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        // 切割字符串
        String result = respons1.getStatusLine().toString().split(" ")[1];

        try {
            client.close();// 释放资源
        } catch (IOException e) {
            System.out.println("请求连接无法关闭,关注get方法!");
            e.printStackTrace();
        }
        return result;

    }

    // 常规P0ST请求
    public static String HttpPostWithJson(String url, String json) {

        String returnValue = "这是默认返回值,接口调用失败";
        CloseableHttpClient httpClient = HttpClients.createDefault();
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        try {
            // 创建HttpClient对象
            httpClient = HttpClients.createDefault();
            // 创建httpPost对象
            HttpPost httpPost = new HttpPost(url);
            // 给httpPost设置JSON格式的参数
            StringEntity requestEntity = new StringEntity(json, "utf-8");
            requestEntity.setContentEncoding("UTF-8");
            httpPost.setHeader("Content-type", "application/json");
            httpPost.setEntity(requestEntity);
            // 发送HttpPost请求,获取返回值
            returnValue = httpClient.execute(httpPost, responseHandler); // 调接口获取返回值,用此方法
        } catch (Exception e) {
            System.out.println("请求返回值为空!");
            e.printStackTrace();
        }

        finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                System.out.println("请求连接无法关闭,关注post方法!");
                e.printStackTrace();
            }
        }
        // 第五步:处理返回值
        return returnValue;
    }

    // 忽略证书的HTTPS请求 - get
    public static String HttpsGetIgnoreCertification(String url)
            throws NoSuchAlgorithmException, KeyManagementException, ClientProtocolException, IOException {
        // First create a trust manager that won't care.
        X509TrustManager trustManager = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // Don't do anything.
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // Don't do anything.
            }

            public X509Certificate[] getAcceptedIssuers() {
                // Don't do anything.
                return null;
            }

        };
        // 现在将信任管理器放到SSLContext中。
        SSLContext sslcontext = SSLContext.getInstance("SSL");
        sslcontext.init(null, new TrustManager[] { trustManager }, null);
        SSLSocketFactory sf = new SSLSocketFactory(sslcontext);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        DefaultHttpClient httpclient = new DefaultHttpClient();
        httpclient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", sf, 443));

        HttpGet httpget = new HttpGet(url);
//        String result = "";
        httpget.setHeader("Content-type", "application/json");
        HttpResponse response = httpclient.execute(httpget);
        HttpEntity entity = response.getEntity();
        EntityUtils.consume(entity);
//        String result1 = response.getStatusLine().toString();
//        String result2 = response.getStatusLine().toString().split(" ")[2];
        String result3 = response.getStatusLine().toString().split(" ")[1];
        return result3;

    }

    // 忽略证书的HTTPS请求 - post
    public static String HttpsPostIgnoreCertification(String url, String requestData)
            throws NoSuchAlgorithmException, KeyManagementException, ClientProtocolException, IOException {
        // First create a trust manager that won't care.
        X509TrustManager trustManager = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // Don't do anything.
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                // Don't do anything.
            }

            public X509Certificate[] getAcceptedIssuers() {
                // Don't do anything.
                return null;
            }

        };
        // 现在将信任管理器放到SSLContext中。
        SSLContext sslcontext = SSLContext.getInstance("SSL");
        sslcontext.init(null, new TrustManager[] { trustManager }, null);
        SSLSocketFactory sf = new SSLSocketFactory(sslcontext);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        DefaultHttpClient httpclient = new DefaultHttpClient();
        httpclient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", sf, 443));

        HttpPost httpPost = new HttpPost(url);
        String result = "";
//            httpPost.setHeader("Authorization", "basic " + "dGNsb3VkYWRtaW46dGNsb3VkMTIz");
        httpPost.setHeader("Content-type", "application/json");
        StringEntity reqEntity;
        // 将请求参数封装成HttpEntity
        reqEntity = new StringEntity(requestData);
        BufferedHttpEntity bhe = new BufferedHttpEntity(reqEntity);
        httpPost.setEntity(bhe);

        HttpResponse response = httpclient.execute(httpPost);
        HttpEntity resEntity = response.getEntity();
        InputStreamReader reader = new InputStreamReader(resEntity.getContent());
        // 取内存资源
        char[] buff = new char[1024];
        int length = 0;
        while ((length = reader.read(buff)) != -1) {
            result += new String(buff, 0, length);
        }
        httpclient.close();
        return result;

//            System.out.println(result);
    }

    // 启用HTTPS携带证书GET请求
    public static String HttpsforGet(String url, String keystore_PathFile, String keypwd) throws IOException,
            KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException {
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpClient httpClient = null;
        if (url.startsWith("https")) {
//            "E:\\White_testNG\\mock\\mock_https\\isa\\isa.keystor"
            File cert = new File(keystore_PathFile);
            String keystore = keypwd;
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadTrustMaterial(cert, keystore.toCharArray(), new TrustSelfSignedStrategy()).build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" },
                    null, NoopHostnameVerifier.INSTANCE);
            httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } else {
            httpClient = HttpClients.createDefault();
        }
        try (CloseableHttpClient _httpClient = httpClient; CloseableHttpResponse res = _httpClient.execute(httpGet);) {

            StatusLine sl = res.getStatusLine();
//                System.out.println(sl.toString().split(" ")[1]);
            String result = sl.toString().split(" ")[1];
            /*
             * if (sl != null) { System.out.println(sl.getStatusCode()); StringBuilder
             * builder = new StringBuilder(); try (InputStream is =
             * res.getEntity().getContent(); InputStreamReader isr = new
             * InputStreamReader(is); BufferedReader br = new BufferedReader(isr);) { String
             * line = br.readLine(); while(line != null) { builder.append(line); line =
             * br.readLine(); } System.out.println("响应结果:" + builder.toString());
             */
            return result;
        }
    }

    // 启用HTTPS携带证书post请求
    public static String HttpsforPost(String url, String keystore_PathFile, String keypwd, String json)
            throws ClientProtocolException, IOException, KeyManagementException, NoSuchAlgorithmException,
            KeyStoreException, CertificateException {

        String returnValue = "这是默认返回值,接口调用失败";
        HttpPost httppost = new HttpPost(url);
        CloseableHttpClient httpClient = null;
        if (url.startsWith("https")) {
            File cert = new File(keystore_PathFile);
            String keystore = keypwd;
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadTrustMaterial(cert, keystore.toCharArray(), new TrustSelfSignedStrategy()).build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" },
                    null, NoopHostnameVerifier.INSTANCE);
            httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } else {
            httpClient = HttpClients.createDefault();
        }
        ResponseHandler<String> responseHandler = new BasicResponseHandler();
        try (CloseableHttpClient _httpClient = httpClient; CloseableHttpResponse res = _httpClient.execute(httppost);) {
            StringEntity requestEntity = new StringEntity(json, "utf-8");
            requestEntity.setContentEncoding("UTF-8");
            httppost.setHeader("Content-type", "application/json");
            httppost.setEntity(requestEntity);
            // 发送HttpPost请求,获取返回值
            returnValue = httpClient.execute(httppost, responseHandler); // 调接口获取返回值,用此方法

//                System.out.println(returnValue);

        }
        return returnValue;

    }

}

Reference article

https://www.cnblogs.com/relax-zw/p/9883959.html

https://blog.csdn.net/qq_28165595/article/details/78885775

Released 1385 original articles · won praise 245 · views 340 000 +

Guess you like

Origin blog.csdn.net/weixin_43272781/article/details/104274609