在java开发中,经常遇到需要调用第三方提供的接口服务的需求,下面对实现http请求的方式进行浅入浅析并进行实例尝试。若是普通java工程推荐使用OkHttpClient,若是spring工程推荐使用RestTemplate。
在java开发中,实现访问第三方接口服务的常见方式:
通过JDK类 Java.net.HttpURLConnection;
通过commons-httpclient封装好的HttpClient;
通过org.apache.httpcomponents封装好的CloseableHttpClient;
通过com.squareup.okhttp3封装好的OkHttpClient;
通过springboot中RestTemplate;
JDK原生提供的net包,无需其他jar包,实例如下
public class HttpUrlConnectionClientUtil { /** * 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.setReadTimeout(15000); //开始连接 connection.connect(); //获取响应数据 if (connection.getResponseCode() == 200) { //获取返回的数据 is = connection.getInputStream(); if (null != is) { br = new BufferedReader(new InputStreamReader(is, "UTF-8")); String temp = null; while (null != (temp = br.readLine())) { result.append(temp); } } } } catch (IOException e) { e.printStackTrace(); } finally { if (null != br) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (null != is) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } //关闭远程连接 connection.disconnect(); } return result.toString(); } /** * Http post请求 * @param httpUrl 连接 * @param param 参数 * @return */ public static String doPost(String httpUrl, String param) { HttpURLConnection connection = null; OutputStream os = null; InputStream is = null; BufferedReader br = null; StringBuffer result = new StringBuffer(); try { //创建连接对象 URL url = new URL(httpUrl); //创建连接 connection = (HttpURLConnection) url.openConnection(); //设置请求方法 connection.setRequestMethod("POST"); //设置连接超时时间 connection.setConnectTimeout(15000); //设置读取超时时间 connection.setReadTimeout(15000); //DoOutput设置是否向httpUrlConnection输出,DoInput设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个 //设置是否可读取 connection.setDoOutput(true); connection.setDoInput(true); //设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); connection.setRequestProperty("Content-Type", "application/json;charset=utf-8"); //拼装参数 if (null != param && !param.equals("")) { //设置参数 os = connection.getOutputStream(); //拼装参数 os.write(param.getBytes("UTF-8")); } //读取响应 if (connection.getResponseCode() == 200) { is = connection.getInputStream(); if (null != is) { br = new BufferedReader(new InputStreamReader(is, "UTF-8")); String temp = null; while (null != (temp = br.readLine())) { result.append(temp); result.append("\r\n"); } } } } 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(); } public static void main(String[] args) { String messageByGet = doGet("http://***"); *** resultByGet = JSON.parseObject(messageByGet, ***.class); System.out.println(resultByGet); Map param = new HashMap<>(); param.put("name","admin"); String str = JSON.toJSONString(param); String messageByPost = doPost("http://***", str); *** resultByPost = JSON.parseObject(messageByPost, ***.class); System.out.println(resultByPost); } }
HttpClient别名:HttpComponents
HttpClient可以发送get、post、put、delete、…等请求
引入依赖:
org.apache.httpcomponents httpclient
4.4
发起Get请求
1创建一个客户端 CloseableHttpClient
2创建一个get方法请求实例 HttpGet
3发送请求 execute
4获取响应的头信息
5获取响应的主题内容
6关闭响应对象
public class HttpClientUtil { /** * 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() + "headers:" + 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, String charset){ 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("params", json.toJSONString()); try { postMethod.setRequestEntity(new StringRequestEntity(json.toJSONString(), "application/json", "utf-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } String response = ""; try { int code = httpClient.executeMethod(postMethod); if (code == 200){ byte[] responseBody = postMethod.getResponseBody(); response = new String(responseBody, charset); System.out.println("response:" + response); // 返回值中文乱码 //response = postMethod.getResponseBodyAsString(); } } catch (IOException e) { e.printStackTrace(); } return response; } public static void main(String[] args) { String messageByGet = doGet("http://***", "UTF-8"); System.out.println(messageByGet); JSONObject jsonObject = new JSONObject(); jsonObject.put("name","admin"); String messageByPost = doPost("http://***", jsonObject, "UTF-8"); System.out.println(messageByPost); } }
/*
* 演示:使用HttpClient发起带有参数的POST请求
*/
public class DoPOSTParam { public static void main(String[] args) throws Exception { // 创建Httpclient对象 CloseableHttpClient httpclient = HttpClients.createDefault(); // 创建http POST请求,访问开源中国 HttpPost httpPost = new HttpPost("http://www.oschina.net/search"); // 根据开源中国的请求需要,设置post请求参数 Listparameters = new ArrayList (0); parameters.add(new BasicNameValuePair("scope", "project")); parameters.add(new BasicNameValuePair("q", "java")); parameters.add(new BasicNameValuePair("fromerr", "8bDnUWwC")); // 构造一个form表单式的实体 UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters); // 将请求实体设置到httpPost对象中 httpPost.setEntity(formEntity); CloseableHttpResponse response = null; try { // 执行请求 response = httpclient.execute(httpPost); // 判断返回状态是否为200 if (response.getStatusLine().getStatusCode() == 200) { // 解析响应体 String content = EntityUtils.toString(response.getEntity(), "UTF-8"); System.out.println(content); } } finally { if (response != null) { response.close(); } // 关闭浏览器 httpclient.close(); } } }
org.apache.httpcomponents httpclient
4.5.2
public class CloseableHttpClientUtil { private static String tokenString = ""; private static String AUTH_TOKEN_EXPIRED = "AUTH_TOKEN_EXPIRED"; private static CloseableHttpClient httpClient = null; /** * 以get方式调用第三方接口 * @param url * @param token * @return */ public static String doGet(String url, String token) { //创建HttpClient对象 CloseableHttpClient httpClient = HttpClientBuilder.create().build(); HttpGet httpGet = new HttpGet(url); if (null != tokenString && !tokenString.equals("")) { tokenString = getToken(); } //api_gateway_auth_token自定义header头,用于token验证使用 httpGet.addHeader("api_gateway_auth_token",tokenString); httpGet.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"); try { HttpResponse response = httpClient.execute(httpGet); 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) { if (null == httpClient) { httpClient = HttpClientBuilder.create().build(); } HttpPost httpPost = new HttpPost(url); if (null != tokenString && tokenString.equals("")) { tokenString = getToken(); } //api_gateway_auth_token自定义header头,用于token验证使用 httpPost.addHeader("api_gateway_auth_token", tokenString); httpPost.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"); try { StringEntity stringEntity = new StringEntity(json.toString()); stringEntity.setContentEncoding("UTF-8"); //发送json数据需要设置contentType stringEntity.setContentType("application/json;charset=utf-8"); //设置请求参数 httpPost.setEntity(stringEntity); HttpResponse response = httpClient.execute(httpPost); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { //返回json格式 String res = EntityUtils.toString(response.getEntity()); return res; } } catch (IOException e) { e.printStackTrace(); } finally { if (httpClient != null){ try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } public static void main(String[] args) { String messageByGet = doGet("http://***", ""); System.out.println(messageByGet); JSONObject jsonObject = new JSONObject(); jsonObject.put("name","admin"); String response = doPost("http://***", jsonObject); System.out.println(response); } }
com.squareup.okhttp3 okhttp
3.10.0
@Slf4j public class OkHttpClientUtil { private volatile static OkHttpClient client; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); private static final int MAX_IDLE_CONNECTION = 10; private static final long KEEP_ALIVE_DURATION = 60; private static final long CONNECT_TIMEOUT = 30; private static final long READ_TIMEOUT = 30; /** * 单例模式(双重检查模式) 获取类实例 * * @return client */ private static OkHttpClient getInstance() { if (client == null) { synchronized (OkHttpClient.class) { if (client == null) { client = new OkHttpClient.Builder() .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS) .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS) .connectionPool(new ConnectionPool(MAX_IDLE_CONNECTION, KEEP_ALIVE_DURATION,TimeUnit.MINUTES)) .build(); } } } return client; } public static String syncPost(String url, String json) { RequestBody body = RequestBody.create(JSON, json); Request request = new Request.Builder() .url(url) .post(body) .build(); try { Response response = OkHttpClientUtil.getInstance().newCall(request).execute(); if (response.isSuccessful()) { String result = response.body().string(); log.info("syncPost response = {}, responseBody= {}", response, result); return result; } String result = response.body().string(); log.info("syncPost response = {}, responseBody= {}", response, result); throw new IOException("三方接口返回http状态码为" + response.code()); } catch (Exception e) { log.error("syncPost() url:{} have a ecxeption {}", url, e); throw new RuntimeException("syncPost() have a ecxeption {}" + e.getMessage()); } } public static String syncGet(String url, MapheadParamsMap) { Request request; final Request.Builder builder = new Request.Builder().url(url); try { if (!CollectionUtils.isEmpty(headParamsMap)) { final Iterator > iterator = headParamsMap.entrySet().iterator(); while (iterator.hasNext()) { final Map.Entry entry = iterator.next(); builder.addHeader(entry.getKey(), (String) entry.getValue()); } } request = builder.build(); Response response = OkHttpClientUtil.getInstance().newCall(request).execute(); String result = response.body().string(); log.info("syncGet response = {},responseBody= {}", response, result); if (!response.isSuccessful()) { throw new IOException("三方接口返回http状态码为" + response.code()); } return result; } catch (Exception e) { log.error("remote interface url:{} have a ecxeption {}", url, e); throw new RuntimeException("三方接口返回异常"); } } public static void main(String[] args) { String messageByGet = syncGet("http://***", null); System.out.println(messageByGet); JSONObject jsonObject = new JSONObject(); jsonObject.put("pageNum", 1); jsonObject.put("pageSize", 10); jsonObject.put("name","admin"); String messageByPost = syncPost("http://***", jsonObject.toJSONString()); System.out.println(messageByPost); } }
RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。RestTemplate提供了常见的REST请求方案的模版,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。
org.springframework.boot spring-boot-starter-web
设置配置类
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(ClientHttpRequestFactory factory){ return new RestTemplate(factory); } @Bean public ClientHttpRequestFactory simpleClientHttpRequestFactory(){ SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(15000); factory.setReadTimeout(5000); return factory; } }
测试
@Autowired private RestTemplate restTemplate; private static final String getUrl = "http://***"; private static final String postUrl = "http://***"; @Test void get1() { ResponseEntityresponseEntity = restTemplate.getForEntity(getUrl, ResponseData.class); ResponseData responseData = responseEntity.getBody(); System.out.println(responseData); } @Test void get2() { ResponseData responseData = restTemplate.getForObject(getUrl, ResponseData.class); System.out.println(responseData); } @Test void post1() { Map param = new HashMap<>(); param.put("name","admin"); ResponseEntity responseEntity = restTemplate.postForEntity(postUrl, param, String.class); String body = responseEntity.getBody(); System.out.println(body); } @Test void post2() { Map param = new HashMap<>(); param.put("name","admin"); String body = restTemplate.postForObject(postUrl, param, String.class); System.out.println(body); } @Test void exchange() { //header参数 HttpHeaders headers = new HttpHeaders(); String token = "1234567890"; headers.add("Authorization", token); headers.setContentType(MediaType.APPLICATION_JSON); //放入body中的json参数 JSONObject jsonObject = new JSONObject(); jsonObject.put("pageNum", 1); jsonObject.put("pageSize", 10); jsonObject.put("name","admin"); //组装 HttpEntity request = new HttpEntity<>(jsonObject, headers); ResponseEntity responseEntity = restTemplate.exchange(postUrl, HttpMethod.POST, request, String.class); String body = responseEntity.getBody(); System.out.println(body); }