网络通信——HTTP接口访问——GET方式调用HTTP接口

桃扇骨 2024-04-03 12:54 215阅读 0赞

54f0eaf23f89a62e671351752107ef7c.png

HttpURLConnection访问HTTP接口的注意点:(1)HttpURLConnection默认采取UTF-8编码,但服务器可能返回GBK编码的报文;(2)有时服务器会先压缩应答报文,再把压缩后的数据送给调用方;(3)服务器返回报文超长的时候,不要企图一次性把返回数据读到某个字节数组,而要循环读取输入流中的字节数据,直到确定读完了全部的应答数据;

260f149ef5e41a162a273f35d7b3a4b6.png

643014e0d8a8b84152d0f382cdf9fb96.png

10b30e9006249de2b17137759bb7c3ae.png

1b514db9c4dd47a9fcdc7168d4c63d23.png

==============================================================================================================

AndroidManifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. package="com.example.myapplication">
  5. <!-- 互联网 -->
  6. <uses-permission android:name="android.permission.INTERNET" />
  7. <!-- 定位 -->
  8. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  9. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  10. <!-- 存储卡读写 -->
  11. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  12. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  13. <!-- 下载时不提示通知栏 -->
  14. <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
  15. <!-- 相机 -->
  16. <uses-permission android:name="android.permission.CAMERA" />
  17. <!-- 录音 -->
  18. <uses-permission android:name="android.permission.RECORD_AUDIO" />
  19. <!-- 存储卡读写 -->
  20. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  21. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  22. <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
  23. <application
  24. android:allowBackup="true"
  25. android:dataExtractionRules="@xml/data_extraction_rules"
  26. android:fullBackupContent="@xml/backup_rules"
  27. android:icon="@mipmap/ic_launcher"
  28. android:label="@string/app_name"
  29. android:roundIcon="@mipmap/ic_launcher_round"
  30. android:supportsRtl="true"
  31. android:theme="@style/Theme.MyApplication"
  32. android:usesCleartextTraffic="true"
  33. tools:targetApi="31">
  34. <activity
  35. android:name=".MainActivity7"
  36. android:exported="false" />
  37. <activity
  38. android:name=".MainActivity6"
  39. android:exported="false" />
  40. <activity
  41. android:name=".MainActivity5"
  42. android:exported="false"
  43. android:label="@string/title_activity_main5" />
  44. <activity
  45. android:name=".MainActivity4"
  46. android:exported="false"
  47. android:label="@string/title_activity_main4" />
  48. <activity
  49. android:name=".MainActivity3"
  50. android:exported="false"
  51. android:label="@string/title_activity_main3" />
  52. <activity
  53. android:name=".MainActivity2"
  54. android:exported="false"
  55. android:label="@string/title_activity_main2" />
  56. <activity
  57. android:name=".MainActivity"
  58. android:exported="true">
  59. <!-- android:theme="@style/AppCompatTheme" /> -->
  60. <intent-filter>
  61. <action android:name="android.intent.action.MAIN" />
  62. <category android:name="android.intent.category.LAUNCHER" />
  63. </intent-filter>
  64. </activity>
  65. </application>
  66. </manifest>

布局:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:orientation="vertical"
  5. android:padding="5dp" >
  6. <TextView
  7. android:id="@+id/tv_location"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:text="暂未获取到定位对象"
  11. android:textColor="@color/black"
  12. android:textSize="17sp" />
  13. </LinearLayout>

b7fe8972b7c0df060b8fbcd31ed68a1a.png

主代码:

  1. package com.example.myapplication;
  2. import android.Manifest;
  3. import android.annotation.SuppressLint;
  4. import android.content.Context;
  5. import android.content.pm.PackageManager;
  6. import android.location.Location;
  7. import android.location.LocationManager;
  8. import android.os.Bundle;
  9. import android.util.Log;
  10. import android.widget.TextView;
  11. import android.widget.Toast;
  12. import androidx.appcompat.app.AppCompatActivity;
  13. import androidx.core.app.ActivityCompat;
  14. import com.example.myapplication.task.GetAddressTask;
  15. import com.example.myapplication.util.DateUtil;
  16. import com.example.myapplication.util.SwitchUtil;
  17. @SuppressLint("DefaultLocale")
  18. public class MainActivity extends AppCompatActivity implements GetAddressTask.OnAddressListener
  19. {
  20. private final static String TAG = "HttpGetActivity";
  21. private TextView tv_location;
  22. private Location mLocation; // 定位信息
  23. @Override
  24. protected void onCreate(Bundle savedInstanceState)
  25. {
  26. super.onCreate(savedInstanceState);
  27. setContentView(R.layout.activity_main);
  28. tv_location = findViewById(R.id.tv_location);
  29. SwitchUtil.checkGpsIsOpen(this, "需要打开定位功能才能查看定位结果信息"); // 检查定位功能是否打开,若未打开则跳到系统的定位功能设置页面
  30. }
  31. @Override
  32. protected void onResume()
  33. {
  34. super.onResume();
  35. // 检查当前设备是否已经开启了定位功能
  36. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
  37. {
  38. Toast.makeText(this, "请授予定位权限并开启定位功能", Toast.LENGTH_SHORT).show();
  39. return;
  40. }
  41. // 从系统服务中获取定位管理器
  42. LocationManager mgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
  43. // 获取最后一次成功定位的位置信息(network表示网络定位方式)
  44. Location location = mgr.getLastKnownLocation("network");
  45. getLocationText(location); // 获取定位结果文本
  46. // 获取最后一次成功定位的位置信息(gps表示卫星定位方式)
  47. location = mgr.getLastKnownLocation("gps");
  48. getLocationText(location); // 获取定位结果文本
  49. }
  50. // 获取定位结果文本
  51. private void getLocationText(Location location)
  52. {
  53. if (location != null)
  54. {
  55. mLocation = location;
  56. refreshLocationInfo(""); // 刷新定位信息
  57. GetAddressTask task = new GetAddressTask(); // 创建一个详细地址查询的异步任务
  58. task.setOnAddressListener(this); // 设置详细地址查询的监听器
  59. task.execute(location); // 把详细地址查询任务加入到处理队列
  60. }
  61. }
  62. // 在找到详细地址后触发
  63. @Override
  64. public void onFindAddress(String address)
  65. {
  66. refreshLocationInfo(address); // 刷新定位信息
  67. }
  68. // 刷新定位信息
  69. private void refreshLocationInfo(String address)
  70. {
  71. String desc = String.format("定位类型=%s\n定位对象信息如下: " + "\n\t其中时间:%s" + "\n\t其中经度:%f,纬度:%f" + "\n\t其中高度:%d米,精度:%d米" + "\n\t其中地址:%s",
  72. mLocation.getProvider(), DateUtil.formatDate(mLocation.getTime()),
  73. mLocation.getLongitude(), mLocation.getLatitude(),
  74. Math.round(mLocation.getAltitude()), Math.round(mLocation.getAccuracy()), address);
  75. tv_location.setText(desc);
  76. }
  77. }
  78. DateUtil
  79. package com.example.myapplication.util;
  80. import android.annotation.SuppressLint;
  81. import android.text.TextUtils;
  82. import java.text.SimpleDateFormat;
  83. import java.util.Date;
  84. @SuppressLint("SimpleDateFormat")
  85. public class DateUtil {
  86. // 获取当前的日期时间
  87. public static String getNowDateTime() {
  88. SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
  89. return sdf.format(new Date());
  90. }
  91. // 获取当前的时间
  92. public static String getNowTime() {
  93. SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
  94. return sdf.format(new Date());
  95. }
  96. // 获取当前的时间(精确到毫秒)
  97. public static String getNowTimeDetail() {
  98. SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
  99. return sdf.format(new Date());
  100. }
  101. // 获取指定格式的日期时间
  102. public static String getNowDateTime(String formatStr) {
  103. String format = formatStr;
  104. if (TextUtils.isEmpty(format)) {
  105. format = "yyyyMMddHHmmss";
  106. }
  107. SimpleDateFormat sdf = new SimpleDateFormat(format);
  108. return sdf.format(new Date());
  109. }
  110. public static String formatDate(long time) {
  111. Date date = new Date(time);
  112. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  113. return sdf.format(date);
  114. }
  115. // 重新格式化日期字符串
  116. public static String convertDateString(String strTime) {
  117. String newTime = strTime;
  118. try {
  119. SimpleDateFormat oldFormat = new SimpleDateFormat("yyyyMMddHHmmss");
  120. Date date = oldFormat.parse(strTime);
  121. SimpleDateFormat newFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  122. newTime = newFormat.format(date);
  123. } catch (Exception e) {
  124. e.printStackTrace();
  125. }
  126. return newTime;
  127. }
  128. }
  129. SwitchUtil
  130. package com.example.myapplication.util;
  131. import android.content.Context;
  132. import android.content.Intent;
  133. import android.location.LocationManager;
  134. import android.net.wifi.WifiManager;
  135. import android.provider.Settings;
  136. import android.widget.Toast;
  137. public class SwitchUtil
  138. {
  139. // 获取定位功能的开关状态
  140. public static boolean getGpsStatus(Context ctx)
  141. {
  142. // 从系统服务中获取定位管理器
  143. LocationManager lm = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
  144. return lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
  145. }
  146. // 检查定位功能是否打开,若未打开则跳到系统的定位功能设置页面
  147. public static void checkGpsIsOpen(Context ctx, String hint)
  148. {
  149. if (!getGpsStatus(ctx))
  150. {
  151. Toast.makeText(ctx, hint, Toast.LENGTH_SHORT).show();
  152. Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
  153. ctx.startActivity(intent);
  154. }
  155. }
  156. }
  157. GetAddressTask
  158. package com.example.myapplication.task;
  159. import android.location.Location;
  160. import android.os.AsyncTask;
  161. import android.text.TextUtils;
  162. import android.util.Log;
  163. import com.example.myapplication.util.HttpUtil;
  164. import org.json.JSONException;
  165. import org.json.JSONObject;
  166. import java.io.UnsupportedEncodingException;
  167. import java.net.URLEncoder;
  168. // 根据经纬度获取详细地址的异步任务
  169. public class GetAddressTask extends AsyncTask<Location, Void, String> {
  170. private final static String TAG = "GetAddressTask";
  171. private String mQueryUrl = "https://api.tianditu.gov.cn/geocoder?postStr=%s&type=geocode&tk=253b3bd69713d4bdfdc116255f379841";
  172. // 线程正在后台处理
  173. protected String doInBackground(Location... params) {
  174. Location location = params[0];
  175. //String url = String.format(mQueryUrl, mLocation.getLongitude(), mLocation.getLatitude());
  176. String param = String.format("{'lon':%f,'lat':%f,'ver':1}", location.getLongitude(), location.getLatitude());
  177. try {
  178. param = URLEncoder.encode(param, "utf8");
  179. } catch (UnsupportedEncodingException e) {
  180. e.printStackTrace();
  181. }
  182. String url = String.format(mQueryUrl, param);
  183. // // 把经度和纬度代入到URL地址。天地图的地址查询url在UrlConstant.java中定义
  184. // String url = String.format(UrlConstant.GET_ADDRESS_URL,
  185. // location.getLongitude(), location.getLatitude());
  186. Log.d(TAG, "url = " + url);
  187. String resp = HttpUtil.get(url, null); // 发送HTTP请求信息,并获得HTTP应答内容
  188. Log.d(TAG, "resp = " + resp);
  189. String address = "未知";
  190. // 下面从JSON串中解析formatted_address字段获得详细地址描述
  191. if (!TextUtils.isEmpty(resp))
  192. {
  193. try
  194. {
  195. JSONObject obj = new JSONObject(resp);
  196. JSONObject result = obj.getJSONObject("result");
  197. address = result.getString("formatted_address");
  198. }
  199. catch (JSONException e)
  200. {
  201. e.printStackTrace();
  202. }
  203. }
  204. Log.d(TAG, "address = " + address);
  205. return address; // 返回HTTP应答内容中的详细地址
  206. }
  207. // 线程已经完成处理
  208. protected void onPostExecute(String address)
  209. {
  210. mListener.onFindAddress(address); // HTTP调用完毕,触发监听器的找到地址事件
  211. }
  212. private OnAddressListener mListener; // 声明一个查询详细地址的监听器对象
  213. // 设置查询详细地址的监听器
  214. public void setOnAddressListener(OnAddressListener listener)
  215. {
  216. mListener = listener;
  217. }
  218. // 定义一个查询详细地址的监听器接口
  219. public interface OnAddressListener
  220. {
  221. void onFindAddress(String address);
  222. }
  223. }
  224. HttpUtil
  225. package com.example.myapplication.util;
  226. import android.graphics.Bitmap;
  227. import android.graphics.BitmapFactory;
  228. import android.util.Log;
  229. import java.io.ByteArrayOutputStream;
  230. import java.io.DataOutputStream;
  231. import java.io.FileInputStream;
  232. import java.io.IOException;
  233. import java.io.InputStream;
  234. import java.io.OutputStream;
  235. import java.net.HttpURLConnection;
  236. import java.net.URL;
  237. import java.security.SecureRandom;
  238. import java.security.cert.X509Certificate;
  239. import java.util.Map;
  240. import java.util.zip.GZIPInputStream;
  241. import javax.net.ssl.HostnameVerifier;
  242. import javax.net.ssl.HttpsURLConnection;
  243. import javax.net.ssl.SSLContext;
  244. import javax.net.ssl.SSLSession;
  245. import javax.net.ssl.TrustManager;
  246. import javax.net.ssl.X509TrustManager;
  247. public class HttpUtil {
  248. private final static String TAG = "HttpUtil";
  249. private final static int CONNECT_TIMEOUT = 15000;
  250. private final static int READ_TIMEOUT = 15000;
  251. // 兼容https开头的调用地址
  252. private static void compatibleSSL(String callUrl) throws Exception {
  253. if (callUrl.toLowerCase().startsWith("https")) {
  254. SSLContext sc = SSLContext.getInstance("TLS");
  255. sc.init(null, new TrustManager[]{
  256. new X509TrustManager() {
  257. @Override
  258. public X509Certificate[] getAcceptedIssuers() {
  259. return null;
  260. }
  261. @Override
  262. public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
  263. }
  264. @Override
  265. public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
  266. }
  267. }}, new SecureRandom());
  268. HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
  269. HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
  270. @Override
  271. public boolean verify(String hostname, SSLSession session) {
  272. return true;
  273. }
  274. });
  275. }
  276. }
  277. // 对指定接口地址发起GET调用
  278. public static String get(String callUrl, Map<String, String> headers)
  279. {
  280. String resp = ""; // 应答内容
  281. try
  282. {
  283. Log.d(TAG, "请求地址:"+callUrl);
  284. compatibleSSL(callUrl); // 兼容https开头的调用地址
  285. URL url = new URL(callUrl); // 根据网址字符串构建URL对象
  286. // 打开URL对象的网络连接,并返回HttpURLConnection连接对象
  287. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  288. conn.setRequestMethod("GET"); // 设置请求方式
  289. setConnHeader(conn, headers);// 设置HTTP连接的头部信息
  290. conn.connect(); // 开始连接
  291. // 打印HTTP调用的应答内容长度、内容类型、压缩方式
  292. Log.d(TAG, String.format("应答内容长度=%d, 内容类型=%s, 压缩方式=%s", conn.getContentLength(), conn.getContentType(), conn.getContentEncoding()) );
  293. // 对输入流中的数据解压和字符编码,得到原始的应答字符串
  294. resp = getUnzipString(conn);
  295. // 打印HTTP调用的应答状态码和应答报文
  296. Log.d(TAG, String.format("应答状态码=%d, 应答报文=%s", conn.getResponseCode(), resp) );
  297. conn.disconnect(); // 断开连接
  298. }
  299. catch (Exception e)
  300. {
  301. e.printStackTrace();
  302. }
  303. return resp;
  304. }
  305. // 从指定url获取图片
  306. public static Bitmap getImage(String callUrl, Map<String, String> headers) {
  307. Bitmap bitmap = null; // 位图对象
  308. try {
  309. Log.d(TAG, "请求地址:"+callUrl);
  310. compatibleSSL(callUrl); // 兼容https开头的调用地址
  311. URL url = new URL(callUrl); // 根据网址字符串构建URL对象
  312. // 打开URL对象的网络连接,并返回HttpURLConnection连接对象
  313. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  314. conn.setRequestMethod("GET"); // 设置请求方式
  315. setConnHeader(conn, headers);// 设置HTTP连接的头部信息
  316. conn.connect(); // 开始连接
  317. // 打印图片获取的应答内容长度、内容类型、压缩方式
  318. Log.d(TAG, String.format("应答内容长度=%d, 内容类型=%s, 压缩方式=%s",
  319. conn.getContentLength(), conn.getContentType(), conn.getContentEncoding()) );
  320. // 对输入流中的数据解码,得到位图对象
  321. bitmap = BitmapFactory.decodeStream(conn.getInputStream());
  322. // 打印图片获取的应答状态码和位图大小
  323. Log.d(TAG, String.format("应答状态码=%d, 位图大小=%s", conn.getResponseCode(), bitmap.getByteCount()) );
  324. conn.disconnect(); // 断开连接
  325. } catch (Exception e) {
  326. e.printStackTrace();
  327. }
  328. return bitmap;
  329. }
  330. // 对指定接口地址发起POST调用
  331. public static String post(String callUrl, String req, Map<String, String> headers) {
  332. String resp = ""; // 应答内容
  333. try {
  334. Log.d(TAG, "请求地址:"+callUrl+", 请求报文="+req);
  335. compatibleSSL(callUrl); // 兼容https开头的调用地址
  336. URL url = new URL(callUrl); // 根据网址字符串构建URL对象
  337. // 打开URL对象的网络连接,并返回HttpURLConnection连接对象
  338. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  339. conn.setRequestMethod("POST"); // 设置请求方式
  340. setConnHeader(conn, headers);// 设置HTTP连接的头部信息
  341. conn.setRequestProperty("Content-Type", "application/json"); // 请求报文为json格式
  342. conn.setDoOutput(true); // 准备让连接执行输出操作。默认为false,POST方式需要设置为true
  343. //conn.setDoInput(true); // 准备让连接执行输入操作。默认为true
  344. conn.connect(); // 开始连接
  345. OutputStream os = conn.getOutputStream(); // 从连接对象中获取输出流
  346. os.write(req.getBytes()); // 往输出流写入请求报文
  347. // 打印HTTP调用的应答内容长度、内容类型、压缩方式
  348. Log.d(TAG, String.format("应答内容长度=%s, 内容类型=%s, 压缩方式=%s",
  349. conn.getHeaderField("Content-Length"), conn.getHeaderField("Content-Type"),
  350. conn.getHeaderField("Content-Encoding")) );
  351. // 对输入流中的数据解压和字符编码,得到原始的应答字符串
  352. resp = getUnzipString(conn);
  353. // 打印HTTP调用的应答状态码和应答报文
  354. Log.d(TAG, String.format("应答状态码=%d, 应答报文=%s", conn.getResponseCode(), resp) );
  355. conn.disconnect(); // 断开连接
  356. } catch (Exception e) {
  357. e.printStackTrace();
  358. }
  359. return resp;
  360. }
  361. // 把文件上传给指定的URL
  362. public static String upload(String uploadUrl, String uploadFile, Map<String, String> headers)
  363. {
  364. String resp = ""; // 应答内容
  365. // 从本地文件路径获取文件名
  366. String fileName = uploadFile.substring(uploadFile.lastIndexOf("/"));
  367. String end = "\r\n"; // 结束字符串
  368. String hyphens = "--"; // 连接字符串
  369. String boundary = "WUm4580jbtwfJhNp7zi1djFEO3wNNm"; // 边界字符串
  370. try (FileInputStream fis = new FileInputStream(uploadFile)) {
  371. Log.d(TAG, "上传地址:"+uploadUrl+", 上传文件="+uploadFile);
  372. compatibleSSL(uploadUrl); // 兼容https开头的调用地址
  373. URL url = new URL(uploadUrl); // 根据网址字符串构建URL对象
  374. // 打开URL对象的网络连接,并返回HttpURLConnection连接对象
  375. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  376. conn.setRequestMethod("POST"); // 设置请求方式
  377. setConnHeader(conn, headers);// 设置HTTP连接的头部信息
  378. conn.setDoOutput(true); // 准备让连接执行输出操作。默认为false,POST方式需要设置为true
  379. //conn.setDoInput(true); // 准备让连接执行输入操作。默认为true
  380. conn.setRequestProperty("Connection", "Keep-Alive"); // 连接过程要保持活跃
  381. // 请求报文要求分段传输,并且各段之间以边界字符串隔开
  382. conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
  383. // 根据连接对象的输出流构建数据输出流
  384. DataOutputStream ds = new DataOutputStream(conn.getOutputStream());
  385. // 以下写入请求报文的头部
  386. ds.writeBytes(hyphens + boundary + end);
  387. ds.writeBytes("Content-Disposition: form-data; "
  388. + "name=\"file\";filename=\"" + fileName + "\"" + end);
  389. ds.writeBytes(end);
  390. // 以下写入请求报文的主体
  391. byte[] buffer = new byte[1024];
  392. int length;
  393. // 先将文件数据写入到缓冲区,再将缓冲数据写入输出流
  394. while ((length = fis.read(buffer)) != -1) {
  395. ds.write(buffer, 0, length);
  396. }
  397. ds.writeBytes(end);
  398. // 以下写入请求报文的尾部
  399. ds.writeBytes(hyphens + boundary + hyphens + end);
  400. ds.close(); // 关闭数据输出流
  401. // 打印HTTP调用的应答内容长度、内容类型、压缩方式
  402. Log.d(TAG, String.format("应答内容长度=%s, 内容类型=%s, 压缩方式=%s",
  403. conn.getHeaderField("Content-Length"), conn.getHeaderField("Content-Type"),
  404. conn.getHeaderField("Content-Encoding")) );
  405. // 对输入流中的数据解压和字符编码,得到原始的应答字符串
  406. resp = getUnzipString(conn);
  407. // 打印HTTP上传的应答状态码和应答报文
  408. Log.d(TAG, String.format("应答状态码=%d, 应答报文=%s", conn.getResponseCode(), resp) );
  409. conn.disconnect(); // 断开连接
  410. }
  411. catch (Exception e)
  412. {
  413. e.printStackTrace();
  414. }
  415. return resp;
  416. }
  417. // 设置HTTP连接的头部信息
  418. private static void setConnHeader(HttpURLConnection conn, Map<String, String> headers)
  419. {
  420. conn.setConnectTimeout(CONNECT_TIMEOUT); // 设置连接的超时时间,单位毫秒
  421. conn.setReadTimeout(READ_TIMEOUT); // 设置读取应答数据的超时时间,单位毫秒
  422. conn.setRequestProperty("Accept", "*/*"); // 设置数据格式
  423. conn.setRequestProperty("Accept-Language", "zh-CN"); // 设置文本语言
  424. conn.setRequestProperty("Accept-Encoding", "gzip, deflate"); // 设置编码格式
  425. // 设置用户代理,包括操作系统版本、浏览器版本等等
  426. conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0");
  427. if (headers != null)
  428. {
  429. for (Map.Entry<String, String> item : headers.entrySet())
  430. {
  431. conn.setRequestProperty(item.getKey(), item.getValue());
  432. }
  433. }
  434. }
  435. // 把输入流中的数据按照指定字符编码转换为字符串。处理大量数据需要使用本方法
  436. private static String isToString(InputStream is, String charset)
  437. {
  438. String result = "";
  439. // 创建一个字节数组的输出流对象
  440. try (ByteArrayOutputStream baos = new ByteArrayOutputStream())
  441. {
  442. int i = -1;
  443. while ((i = is.read()) != -1) // 循环读取输入流中的字节数据
  444. {
  445. baos.write(i); // 把字节数据写入字节数组输出流
  446. }
  447. byte[] data = baos.toByteArray(); // 把字节数组输出流转换为字节数组
  448. result = new String(data, charset); // 将字节数组按照指定的字符编码生成字符串
  449. }
  450. catch (Exception e)
  451. {
  452. e.printStackTrace();
  453. }
  454. return result; // 返回转换后的字符串
  455. }
  456. // 从HTTP连接中获取已解压且重新编码后的应答报文
  457. private static String getUnzipString(HttpURLConnection conn) throws IOException
  458. {
  459. String contentType = conn.getContentType(); // 获取应答报文的内容类型(包括字符编码)
  460. String charset = "UTF-8"; // 默认的字符编码为UTF-8
  461. if (contentType != null)
  462. {
  463. if (contentType.toLowerCase().contains("charset=gbk")) // 应答报文采用gbk编码
  464. {
  465. charset = "GBK"; // 字符编码改为GBK
  466. }
  467. else if (contentType.toLowerCase().contains("charset=gb2312")) // 采用gb2312编码
  468. {
  469. charset = "GB2312"; // 字符编码改为GB2312
  470. }
  471. }
  472. String contentEncoding = conn.getContentEncoding(); // 获取应答报文的压缩方式
  473. InputStream is = conn.getInputStream(); // 获取HTTP连接的输入流对象
  474. String result = "";
  475. if (contentEncoding != null && contentEncoding.contains("gzip")) // 应答报文使用gzip压缩
  476. {
  477. // 根据输入流对象构建压缩输入流
  478. try (GZIPInputStream gis = new GZIPInputStream(is))
  479. {
  480. // 把压缩输入流中的数据按照指定字符编码转换为字符串
  481. result = isToString(gis, charset);
  482. }
  483. catch (Exception e)
  484. {
  485. e.printStackTrace();
  486. }
  487. }
  488. else
  489. {
  490. // 把输入流中的数据按照指定字符编码转换为字符串
  491. result = isToString(is, charset);
  492. }
  493. return result; // 返回处理后的应答报文
  494. }
  495. }

b74d4c6a7854d820e0270c47bf879b12.png

4ec938c0a60695d6cd403ef17e713259.png

a69d91fcbf5a5640cd6ddcc75f8fac1d.png

c7d356ae292197200e767c366c91cbc3.png

7e9e7add966299c3cfbd3da757c3f5f4.png

12bdad4dd2e7b83a8d8f2074cc8eaedd.png

c3d344f946c051b4cc2d2ebecd1ed2c4.png

dbae420ccbf34a059d5dbfb43ea75847.png

0916643385e0076181cfb8c59784e289.png

b6ef8a81de93e3b466f41edf2c1c2cf0.png

5dd04cd4c8d76122b8c7d5678cdea6d4.png

发表评论

表情:
评论列表 (有 0 条评论,215人围观)

还没有评论,来说两句吧...

相关阅读