前言
本文中的內(nèi)容其實嚴(yán)格來說不算springboot里面的特性,屬于JAVA基礎(chǔ),只是我在項目中遇到了,特歸納總結(jié)一下。
HTTP請求封裝
目前JAVA對于HTTP封裝主要有三種方式:
1. JAVA原生封裝
2. HttpClient 3.X /HttpClient4.X
3. Spring RestTemplate
http請求過程如下:
GET:1、創(chuàng)建遠(yuǎn)程連接2、設(shè)置連接方式(get、post、put。。。)3、設(shè)置連接超時時間4、設(shè)置響應(yīng)讀取時間5、發(fā)起請求6、獲取請求數(shù)據(jù)7、關(guān)閉連接POST:1、創(chuàng)建遠(yuǎn)程連接2、設(shè)置連接方式(get、post、put。。。)3、設(shè)置連接超時時間4、設(shè)置響應(yīng)讀取時間5、當(dāng)向遠(yuǎn)程服務(wù)器傳送數(shù)據(jù)/寫數(shù)據(jù)時,需要設(shè)置為true(setDoOutput)6、當(dāng)前向遠(yuǎn)程服務(wù)讀取數(shù)據(jù)時,設(shè)置為true,該參數(shù)可有可無(setDoInput)7、設(shè)置傳入?yún)?shù)的格式:(setRequestProperty)8、設(shè)置鑒權(quán)信息:Authorization:(setRequestProperty)9、設(shè)置參數(shù)10、發(fā)起請求11、獲取請求數(shù)據(jù)12、關(guān)閉連接
JAVA原生:
/** * http get請求 * @param httpUrl 鏈接 * @return 響應(yīng)數(shù)據(jù) */public static String doGet(String httpUrl){ //鏈接 HttpURLConnection connection=null; InputStream is=null; BufferedReader br = null; StringBuffer result=new StringBuffer(); try { //創(chuàng)建連接 URL url=new URL(httpUrl); connection= (HttpURLConnection) url.openConnection(); //設(shè)置請求方式 connection.setRequestMethod("GET"); //設(shè)置連接超時時間 connection.setConnectTimeout(15000); //設(shè)置讀取超時時間 connection.setReadTimeout(15000); //開始連接 connection.connect(); //獲取響應(yīng)數(shù)據(jù) if(connection.getResponseCode()==200){ //獲取返回的數(shù)據(jù) 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();// 關(guān)閉遠(yuǎn)程連接 } return result.toString(); } /** * post請求 * @param httpUrl 鏈接 * @param param 參數(shù) * @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 { //創(chuàng)建連接對象 URL url=new URL(httpUrl); //創(chuàng)建連接 connection= (HttpURLConnection) url.openConnection(); //設(shè)置請求方法 connection.setRequestMethod("POST"); //設(shè)置連接超時時間 connection.setConnectTimeout(15000); //設(shè)置讀取超時時間 connection.setReadTimeout(15000); //設(shè)置是否可讀取 connection.setDoOutput(true); //設(shè)置響應(yīng)是否可讀取 connection.setDoInput(true); //設(shè)置參數(shù)類型 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); //拼裝參數(shù) if(param!=null&&!param.equals("")){ //設(shè)置參數(shù) os=connection.getOutputStream(); //拼裝參數(shù) os.write(param.getBytes("UTF-8")); } //設(shè)置權(quán)限 //設(shè)置請求頭等 //開啟連接 //connection.connect(); //讀取響應(yīng) 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); } } } //關(guā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(); } } //關(guān)閉連接 connection.disconnect(); } return result.toString(); }
HttpCLient4.X
httpclient有很多版本,目前最新的版本是4.X了,所以推薦使用4.x的方式進(jìn)行封裝
public static String doGet(String url) { CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; String result = ""; try { // 通過址默認(rèn)配置創(chuàng)建一個httpClient實例 httpClient = HttpClients.createDefault(); // 創(chuàng)建httpGet遠(yuǎn)程連接實例 HttpGet httpGet = new HttpGet(url); // 設(shè)置請求頭信息,鑒權(quán) httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0"); // 設(shè)置配置請求參數(shù) RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 連接主機服務(wù)超時時間 .setConnectionRequestTimeout(35000)// 請求超時時間 .setSocketTimeout(60000)// 數(shù)據(jù)讀取超時時間 .build(); // 為httpGet實例設(shè)置配置 httpGet.setConfig(requestConfig); // 執(zhí)行g(shù)et請求得到返回對象 response = httpClient.execute(httpGet); // 通過返回對象獲取返回數(shù)據(jù) HttpEntity entity = response.getEntity(); // 通過EntityUtils中的toString方法將結(jié)果轉(zhuǎn)換為字符串 result = EntityUtils.toString(entity); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關(guān)閉資源 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 = ""; // 創(chuàng)建httpClient實例 httpClient = HttpClients.createDefault(); // 創(chuàng)建httpPost遠(yuǎn)程連接實例 HttpPost httpPost = new HttpPost(url); // 配置請求參數(shù)實例 RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 設(shè)置連接主機服務(wù)超時時間 .setConnectionRequestTimeout(35000)// 設(shè)置連接請求超時時間 .setSocketTimeout(60000)// 設(shè)置讀取數(shù)據(jù)連接超時時間 .build(); // 為httpPost實例設(shè)置配置 httpPost.setConfig(requestConfig); // 設(shè)置請求頭 httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded"); // 封裝post請求參數(shù) if (null != paramMap && paramMap.size() > 0) { List<NameValuePair> nvps = new ArrayList<NameValuePair>(); // 通過map集成entrySet方法獲取entity Set<Entry<String, Object>> entrySet = paramMap.entrySet(); // 循環(huán)遍歷,獲取迭代器 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設(shè)置封裝好的請求參數(shù) try { httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } try { // httpClient對象執(zhí)行post請求,并返回響應(yīng)參數(shù)對象 httpResponse = httpClient.execute(httpPost); // 從響應(yīng)對象中獲取響應(yīng)內(nèi)容 HttpEntity entity = httpResponse.getEntity(); result = EntityUtils.toString(entity); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { // 關(guān)閉資源 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請求的基礎(chǔ)上面添加了SSL驗證,通過下面的SLLClient 封裝即可,調(diào)用的時候:
httpClient = SSLClient.createSSLClientDefault();
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返回多層嵌套的方式:
1. 實例化json數(shù)據(jù)
2. 請求Http 接口獲取返回值
3. 實例化返回值并獲取你想要的key或者value,或者做驗證都行
優(yōu)點: 實例化了數(shù)據(jù)結(jié)構(gòu),想獲取任何數(shù)據(jù)都能使用實例化的方法。不用理會它有幾層,它的數(shù)據(jù)結(jié)構(gòu)是什么(List, array, string等等)
缺點: 需要返回的數(shù)據(jù)結(jié)構(gòu)穩(wěn)定,不能返回變動的數(shù)據(jù)結(jié)構(gòu), 另外實例化有一定的代碼量,比較繁瑣(但是有固定插件解決)
實操:
1. IDEA ---settings-----install plugins----GSON 插件
2. 新增一個entity實體類,在新建的實體類使用alt+S 快捷鍵打開GSON插件
3. 輸入你想要實例化的JSON數(shù)據(jù),一直下一步即可完成實例化。
實例化截圖:

Service層調(diào)用實例化:
//實例化的時候注意數(shù)據(jù)格式,List的話可以循環(huán)獲取(下面的注釋部分);最終存儲到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(); //獲取各個區(qū)的名稱// 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);