赞
踩
通过OkHttp拉取网页信息,为OkHttp设置证书验证
以知网为例,https://www.cnki.net/
文件夹中未放置知网证书时,
文件夹中放置了知网证书时,
依赖
//BindView
implementation 'com.jakewharton:butterknife:10.2.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'
//okHttp
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
权限
<uses-permission android:name="android.permission.INTERNET" />
1)数据处理
public class OkHttpManager { public static final String TAG = "OkHttpManager"; /** * CERT_ALIAS 证书别名 */ public static final String CERT_ALIAS = "NCB"; /** * CONNECT_TIME_OUT 连接超时 * READ_TIME_OUT 读超时 * WRITE_TIME_OUT 写超时 */ public static final int CONNECT_TIME_OUT = 75; public static final int READ_TIME_OUT = 75; public static final int WRITE_TIME_OUT = 75; /** * instance 单例 * INSTANCE_LOCK 互斥锁 */ private static OkHttpManager instance = null; private static final Object INSTANCE_LOCK = new Object(); /** * 获取单例 * * @return */ public static OkHttpManager getInstance() { if (instance == null) { synchronized (INSTANCE_LOCK) { if (instance == null) { instance = new OkHttpManager(); } } } return instance; } /** * 获取本地证书 * * @return */ private ArrayList<Certificate> getCertificatesFromAssets(Context context) { ArrayList<Certificate> certificates = new ArrayList<>(); try { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); String certPath = "certs"; AssetManager am = context.getAssets(); String[] list = am.list(certPath); for (int i = 0; i < list.length; i++) { certificates.add(certificateFactory.generateCertificate(am.open(certPath + "/" + list[i]))); Log.i(TAG, "cer name:" + certPath + "/" + list[i]); } return certificates; } catch (Exception e) { e.printStackTrace(); Log.e(TAG, e.getMessage()); } return null; } /** * 获取含证书校验功能的 OkHttpClientBuilder * * @param context * @return */ public OkHttpClient.Builder getOkHttpClientBuilderWithCerts(Context context) { OkHttpClient.Builder builder = new OkHttpClient.Builder(); try { KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); ArrayList<Certificate> localCerts = getCertificatesFromAssets(context); for (int i = 0; i < localCerts.size(); i++) { keyStore.setCertificateEntry(CERT_ALIAS + i, localCerts.get(i)); } SSLContext sslContext = SSLContext.getInstance("TLS"); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom()); SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); final X509TrustManager trustManager = new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }; builder.sslSocketFactory(sslSocketFactory, trustManager); HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; builder.hostnameVerifier(hostnameVerifier); builder.connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS) .readTimeout(READ_TIME_OUT, TimeUnit.SECONDS) .writeTimeout(WRITE_TIME_OUT, TimeUnit.SECONDS); return builder; } catch (Exception e) { e.printStackTrace(); Log.e(TAG, e.getMessage()); } return null; } }
/** * @description 数据处理层 */ public class DataManager { /** * 从服务器获取数据 * * @param url 请求url * @param dataCallback 回调 */ public static void getDataFromServer(Context context, String url, final DataCallback dataCallback) { OkHttpClient.Builder builder = OkHttpManager.getInstance().getOkHttpClientBuilderWithCerts(context); Request request = new Request.Builder().url(url).build(); builder.build().newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { dataCallback.getDataFailed(e.getMessage()); } @Override public void onResponse(Call call, Response response) throws IOException { InputStream inputStream = response.body().byteStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder stringBuilder = new StringBuilder(); String line = ""; while ((line = reader.readLine()) != null) { stringBuilder.append(line); } dataCallback.getDataSuccess(stringBuilder.toString()); } }); } }
public class DataViewModel extends ViewModel { /** * liveData LiveData */ private MutableLiveData<String> liveData; /** * 构造函数 */ public DataViewModel() { liveData = new MutableLiveData<>(); } /** * 获取 LiveData * * @return */ public MutableLiveData<String> getLiveData() { return liveData; } /** * 获取网站数据 * * @param context * @param url */ public void getDataFromServer(Context context, String url) { DataManager.getDataFromServer(context, url, new DataCallback() { @Override public void getDataSuccess(String data) { liveData.postValue("data : \n\n" + data); } @Override public void getDataFailed(String errMsg) { liveData.postValue("error message \n\n: " + errMsg); } }); } }
2)界面布局
abstract public class BaseActivity extends AppCompatActivity { private Unbinder unbinder = null; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getLayoutId()); unbinder = ButterKnife.bind(this); init(); } abstract protected int getLayoutId(); abstract protected void init(); protected BaseActivity getActivity() { return this; } @Override protected void onDestroy() { super.onDestroy(); if (unbinder != null) { unbinder.unbind(); } } }
public class OkHttpActivity extends BaseActivity { //知网 public static final String TEST_URL = "https://www.cnki.net/"; private DataViewModel dataViewModel; @BindView(R.id.id_btn_get_data) TextView btnGetData; @BindView(R.id.id_tv_show_data) TextView tvShowData; @Override protected int getLayoutId() { return R.layout.act_ok_http; } @Override protected void init() { dataViewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory()).get(DataViewModel.class); dataViewModel.getLiveData().observe(this, new Observer<String>() { @Override public void onChanged(String s) { tvShowData.setText(s); } }); tvShowData.setMovementMethod(ScrollingMovementMethod.getInstance()); btnGetData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dataViewModel.getDataFromServer(getActivity(), TEST_URL); } }); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/id_btn_get_data" style="@style/ButtonNormalStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="20dp" android:background="@color/black" android:text="get data" /> <TextView android:id="@+id/id_tv_show_data" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="20dp" android:fadeScrollbars="false" android:scrollbarSize="10dp" android:scrollbars="vertical" android:text="result" android:textSize="30dp" /> </LinearLayout>
以知网为例:https://www.cnki.net/
1、点击“锁”图标
2、点击证书
3、详细信息 -> 复制文件
4、下一页
5、保存
6、完成
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。