前言
本文中的內容其實嚴格來說不算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 封裝即可,調用的時候:
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數據
2. 請求Http 接口獲取返回值
3. 實例化返回值并獲取你想要的key或者value,或者做驗證都行
優點: 實例化了數據結構,想獲取任何數據都能使用實例化的方法。不用理會它有幾層,它的數據結構是什么(List, array, string等等)
缺點: 需要返回的數據結構穩定,不能返回變動的數據結構, 另外實例化有一定的代碼量,比較繁瑣(但是有固定插件解決)
實操:
1. IDEA ---settings-----install plugins----GSON 插件
2. 新增一個entity實體類,在新建的實體類使用alt+S 快捷鍵打開GSON插件
3. 輸入你想要實例化的JSON數據,一直下一步即可完成實例化。
實例化截圖:
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);