Android + https 實現 文件上傳

来源:https://www.cnblogs.com/wbdream/archive/2018/11/21/9993876.html
-Advertisement-
Play Games

package com.example.wbdream.zigvine; import android.annotation.SuppressLint; import android.app.Activity; import android.content.ContentValues; import... ...


package com.example.wbdream.zigvine;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.example.wbdream.zigvine.friends.FriendsData;
import com.example.wbdream.zigvine.friends.FriendsRecyclerAdapter;
import com.example.wbdream.zigvine.https.UpLoadFile;
import com.leon.lfilepickerlibrary.LFilePicker;
import com.leon.lfilepickerlibrary.utils.Constant;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


public class FriendsList extends Fragment {
    private List<JSONObject> mData = null;
    private FriendsData sc = null;
    private SQLiteDatabase db = null;
    private FriendsRecyclerAdapter friendsRecyclerAdapter = null;
    private static final int FILE_CODE = 0;
    private static final String TAG = "FriendsList";
    private String upLoadPath = null;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.e(TAG, "onCreateView: -----finish????-------" );
        setHasOptionsMenu(true);
        final View view = inflater.inflate(R.layout.friends_list,container,false);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        flushData();
        Log.e(TAG, "onActivityCreated: +++++===================" );

//        initData();
//        RecyclerView friends_recycler = getActivity().findViewById(R.id.friends_recycler);
//        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
//        friends_recycler.setLayoutManager(layoutManager);
//        friendsRecyclerAdapter = new FriendsRecyclerAdapter(getContext(),mData);
//        Log.e(TAG, "onActivityCreated: ====================="+friendsRecyclerAdapter.hashCode() );
//        friendsRecyclerAdapter.setOnItemClickListener(new FriendsRecyclerAdapter.OnItemClickListener() {
//            @Override
//            public void onClick(int position) {
//                Toast.makeText(getContext(),"點擊事件"+position,Toast.LENGTH_SHORT).show();
//
//                //初始化某人聊天數據
//                int uid;
//                try {
//                    uid = mData.get(position).getInt("uid");
////                    Cursor cursor = db.rawQuery("select * from CHATRECORD where friends_id = "+ uid,null);
//                    Intent intent = new Intent(getContext(),ChatActivity.class);
//                    intent.putExtra("uid",uid);
//                    startActivity(intent);
//
//                } catch (JSONException e) {
//                    e.printStackTrace();
//                }
//
//            }
//        });
//        friends_recycler.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL));
//        friends_recycler.setAdapter(friendsRecyclerAdapter);
//
//        //刪除資料庫
////        getContext().deleteDatabase("friend1.db");
//
//        //刪除表內容
////        db.execSQL("delete from friends");
//        //插入數據
//        ContentValues values = new ContentValues();
//
////        for ( int i=1;i<3;i++) {
////            Log.e(TAG, "onActivityCreated: ______" + "張三" + i);
////            values.put("friends_name","李四"+i);
////            db.insert("FRIENDS", null,values );
////            values.clear();
////        }
//
//        Toast.makeText(getContext(),"初始化資料庫",Toast.LENGTH_SHORT).show();
//        Cursor cursor = db.rawQuery("select friends_name,friendId from FRIENDS",null);
//        if (cursor.moveToFirst()){
//            do {
//                String name = cursor.getString(cursor.getColumnIndex("friends_name"));
//                Log.e(TAG, "onActivityCreated: *******"+name +"----"+cursor.getInt(cursor.getColumnIndex("friendId")));
//            }while(cursor.moveToNext());
//
//        }
//        cursor.close();

    }
    //添加menu
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.friend_list_menu,menu);
    }
        //menu點擊事件

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.add_friend:
                //跳轉頁面
                Toast.makeText(getContext(),"add friend",Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(getContext(),AddFriendActivity.class);
                startActivity(intent);

                break;
        }
        return true;
    }

    public void initData() {
        //創建資料庫
        sc = new FriendsData(getContext(),"friend.db",null,4);
        db = sc.getWritableDatabase();
        mData = new ArrayList();
        Cursor cursor = db.rawQuery("select * from FRIENDS",null);
        if (cursor.moveToFirst()){
            do {
                JSONObject json=new JSONObject();
                try {
//                    Log.e(TAG, "initData: _________" +cursor.getString(cursor.getColumnIndex("friends_name")));
                    json.put("user_name",cursor.getString(cursor.getColumnIndex("friends_name")));
                    json.put("message","你好呀!");
                    json.put("imageView","");
                    json.put("uid",cursor.getInt(cursor.getColumnIndex("friendId")));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                mData.add(json);
//                Log.e(TAG, "initData: ++++"+mData.size() );
            }while(cursor.moveToNext());

        }
        cursor.close();

    }

    @Override
    public void onResume() {
        Log.e(TAG, "onResume: --------resume------"+friendsRecyclerAdapter.hashCode() );
        Log.e(TAG, "onResume: ==========="+mData.size() );

        flushData();
        super.onResume();
    }

    //刷新數據
    public void flushData(){
        initData();
        RecyclerView friends_recycler = getActivity().findViewById(R.id.friends_recycler);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        friends_recycler.setLayoutManager(layoutManager);
        friendsRecyclerAdapter = new FriendsRecyclerAdapter(getContext(),mData);
        Log.e(TAG, "onActivityCreated: ====================="+friendsRecyclerAdapter.hashCode() );
        friendsRecyclerAdapter.setOnItemClickListener(new FriendsRecyclerAdapter.OnItemClickListener() {
            int uid;
            @Override
            public void onClick(int position) {
                Toast.makeText(getContext(),"點擊事件"+position,Toast.LENGTH_SHORT).show();
                Log.e(TAG, "onClick: ----點擊事件----" );
                //初始化某人聊天數據

                try {
                    uid = mData.get(position).getInt("uid");
//                    Cursor cursor = db.rawQuery("select * from CHATRECORD where friends_id = "+ uid,null);
                    Intent intent = new Intent(getContext(),ChatActivity.class);
                    intent.putExtra("uid",uid);
//                    startActivity(intent);
                    Log.e(TAG, "onClick: ----https--" );
                    @SuppressLint("HandlerLeak") final Handler handler = new Handler(){
                        @Override
                        public void handleMessage(Message msg) {
                            super.handleMessage(msg);
                            switch (msg.what){
                                case 111:
                                    Toast.makeText(getContext(),"jjjj"+msg.obj,Toast.LENGTH_SHORT).show();
                                    break;
                            }
                        }
                    };
                    //文件傳輸
                    String sdpath;
//                    sdpath = "/mnt/";
//                    sdpath = getContext().getFilesDir();
                    Log.e(TAG, "onClick: ----————"+getContext().getFilesDir() );
                    Log.e(TAG, "onClick: ----————"+Environment.getExternalStorageDirectory() );
                    File file = new File(getContext().getFilesDir(),"a2.txt");
                    Log.e(TAG, "onClick: cahgnjan ==========="+!file.exists()+"     "+getContext().getFilesDir() +getContext().getExternalCacheDir() );
                    try {
                        File fp=getContext().getFilesDir();
                        if (!fp.exists()){
                            fp.mkdirs();
                            Log.e(TAG, "onClick: --------創建文件夾" );
                        }
                        getContext().getFilesDir().mkdirs();
                        if (!file.exists()){
                            Log.e(TAG, "onClick: ———創建不成嗎—————" );
                            file.createNewFile();
                            System.out.print("jsdhj");
                            Log.e(TAG, "onClick: --------創建了嗎" );
                        }
                        FileInputStream inputStream = new FileInputStream(file);
                        inputStream.close();
                        FileOutputStream outputStream = new FileOutputStream(file);
                        outputStream.write("hello".getBytes());
                        outputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }


                    new LFilePicker().withSupportFragment(FriendsList.this)
                            .withRequestCode(Constant.ICON_STYLE_BLUE)
                            .withTitle("文件管理器")
//                            .withStartPath("/storage/emulated/0/Download")//指定初始顯示路徑
                            .withStartPath(getContext().getFilesDir().toString())//指定初始顯示路徑
                            .withNotFoundBooks("至少選擇一個文件")
                            .start();
//###############註意這裡是  GET   請求   ##########
                    /////////////////
//                    new Thread(new Runnable() {
//
//                        @Override
//                        public void run() {
//                            getHttps();
//                        }
//                        public void getHttps(){
//                            Log.e(TAG, "getHttps:-------執行了嗎------ https://192.168.1.34:8000/index/" );
//                            String https = "https://192.168.1.34:8000/index/";
//                            try {
//                                SSLContext sc = SSLContext.getInstance("TLS");
//                                sc.init(null,new TrustManager[]{new MyTrustManager()},new SecureRandom());
//                                HttpsURLConnection.setDefaultSSLSocketFactory((sc.getSocketFactory()));
//                                HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier());
//                                HttpsURLConnection conn = (HttpsURLConnection)new URL(https).openConnection();
//                                conn.setDoOutput(true);
//                                conn.setDoInput(true);
//                                Log.e(TAG, "getHttps: ++++++結果111+++++" );
//
//                                conn.connect();
//                                Log.e(TAG, "getHttps: ++++++結果2222+++++" );
//                                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//                                StringBuffer sb = new StringBuffer();
//                                String line;
//                                while ((line = br.readLine())!=null){
//                                    sb.append(line);
//                                }
//                                Log.e(TAG, "getHttps: ++++++結果+++++"+sb.toString() );
//                                Message msg = new Message();
//                                msg.what=111;
//                                msg.obj=sb.toString();
//                                handler.sendMessage(msg);
//                            } catch (NoSuchAlgorithmException e) {
//                                e.printStackTrace();
//                            } catch (KeyManagementException e) {
//                                e.printStackTrace();
//                            } catch (MalformedURLException e) {
//                                e.printStackTrace();
//                            } catch (IOException e) {
//                                e.printStackTrace();
//                            }
//                        }
//                        class MyHostnameVerifier implements HostnameVerifier{
//                            @Override
//                            public boolean verify(String hostname, SSLSession session) {
//                                // TODO Auto-generated method stub
//                                return true;
//                            }
//
//                        }
//
//                        class MyTrustManager implements X509TrustManager{
//                            @Override
//                            public void checkClientTrusted(X509Certificate[] chain, String authType)
//                                    throws CertificateException {
//                                // TODO Auto-generated method stub
//                            }
//                            @Override
//                            public void checkServerTrusted(X509Certificate[] chain, String authType)
//
//                                    throws CertificateException {
//                                // TODO Auto-generated method stub
//                            }
//                            @Override
//                            public X509Certificate[] getAcceptedIssuers() {
//                                // TODO Auto-generated method stub
//                                return null;
//                            }
//
//                        }
//
//                    }).start();



                } catch (JSONException e) {
                    e.printStackTrace();
                }


            }
            //清空聊天記錄
            @Override
            public void clearRecord(int position) {
                try {
                    uid = mData.get(position).getInt("uid");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                db.execSQL("delete from chatrecord where friends_id = "+ uid+";");
                Cursor cursor2 =db.rawQuery("select * from CHATRECORD ;",null);

                Log.e(TAG, "clearRecord: " +cursor2.moveToFirst() + db.equals(null));
                if (cursor2.moveToFirst()){
                    do {
                        Log.e(TAG, "clearRecord: 00-----"+cursor2.getString(cursor2.getColumnIndex("content")) );
                    }while (cursor2.moveToNext());
                }
                Log.e(TAG, "clearRecord: 8888888888" +"delete from CHATRECORD where friends_id ="+ uid);
            }

//            @Override
//            public void onLongClick(int position) {
//                Toast.makeText(getContext(),"長按事件",Toast.LENGTH_SHORT).show();
//                Log.e(TAG, "onLongClick: ___***長按事件**___" );
////                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
////                builder.setTitle("hahahha");
////                builder.show();
//
//                //長按功能鍵
//            }
        });
        friends_recycler.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL));
        friends_recycler.setAdapter(friendsRecyclerAdapter);

        //刪除資料庫
//        getContext().deleteDatabase("friend1.db");

        //刪除表內容
//        db.execSQL("delete from CHATRECORD");
        //插入數據
        ContentValues values = new ContentValues();

//        for ( int i=1;i<3;i++) {
//            Log.e(TAG, "onActivityCreated: ______" + "張三" + i);
//            values.put("friends_name","李四"+i);
//            db.insert("FRIENDS", null,values );
//            values.clear();
//        }

        Toast.makeText(getContext(),"初始化資料庫",Toast.LENGTH_SHORT).show();
        Cursor cursor = db.rawQuery("select friends_name,friendId from FRIENDS",null);
        if (cursor.moveToFirst()){
            do {
                String name = cursor.getString(cursor.getColumnIndex("friends_name"));
                Log.e(TAG, "onActivityCreated: *******"+name +"----"+cursor.getInt(cursor.getColumnIndex("friendId")));
            }while(cursor.moveToNext());

        }
        cursor.close();

    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
//            List<String> list = data.getStringArrayListExtra("paths");
//            String path = data.getStringExtra("path");
//            String param = data.getStringExtra("param");
            List<String> list = null;
            list = data.getStringArrayListExtra(Constant.RESULT_INFO);
            //選中文件
            if (list.size()>0){
                for (String string: list) {
                    Log.e(TAG, "onActivityResult: *************"+string );
                    File file =new File(string);
                    upLoadPath = string;

                    //https請求
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
            //################ 這裡是 認證所有證書 trustAllCerts信任所有的證書###################
                handleSSLHandshake();
            //################  https   POST  請求 #############
                            httpPost("https://192.168.1.32:8000/index/up","/data/user/0/com.example.wbdream.zigvine/files/a2.txt","a2.txt");
//                            httpPost("https://192.168.1.32:8000/index/up",string,file.getName());

                        }
                    }).start();

                    try {
                        FileReader fr=new FileReader(file);
                        byte[] bytes=new byte[1024];
                        BufferedReader br = new BufferedReader(fr);
                        String s="";
                        while ((s=br.readLine())!=null){
                            Log.e(TAG, "onActivityResult: =============="+s );
                        }
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }

            }

        }

    }
    /**
     * 往伺服器上上傳文本  比如log日誌
     * @param urlstr        請求的url
     * @param uploadFile    log日誌的路徑
     *                                    /mnt/shell/emulated/0/LOG/LOG.log
     * @param newName        log日誌的名字 LOG.log
     * @return
     */
    public static void httpPost(String urlstr,String uploadFile,String newName) {
        Log.e(TAG,"urlstr="+urlstr+";uploadFile="+uploadFile+";newName="+newName );
        String end = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";//邊界標識
        int TIME_OUT = 10*1000;   //超時時間
        HttpsURLConnection con = null;
        DataOutputStream ds = null;
        InputStream is = null;
        try {
            URL url = new URL(urlstr);
            con = (HttpsURLConnection) url.openConnection();
            Log.e(TAG, "httpPost: 1111111111" );
            con.setReadTimeout(TIME_OUT);
            con.setConnectTimeout(TIME_OUT);
            /* 允許Input、Output,不使用Cache */
            con.setDoInput(true);
            con.setDoOutput(true);
            con.setUseCaches(false);

            // 設置http連接屬性
            con.setRequestMethod("POST");//請求方式
            con.setRequestProperty("Connection", "Keep-Alive");//在一次TCP連接中可以持續發送多份數據而不會斷開連接
            con.setRequestProperty("Charset", "UTF-8");//設置編碼
            con.setRequestProperty("Content-Type",
                    "multipart/form-data;boundary=" + boundary);//multipart/form-data能上傳文件的編碼格式
            Log.e(TAG, "httpPost: ------------" );
            ds = new DataOutputStream(con.getOutputStream());
            Log.e(TAG, "httpPost: 2222222222" );
            ds.writeBytes(twoHyphens + boundary + end);
            ds.writeBytes("Content-Disposition: form-data; "
                    + "name=\"stblog\";filename=\"" + newName + "\"" + end);
            ds.writeBytes(end);

            // 取得文件的FileInputStream
            FileInputStream fStream = new FileInputStream(uploadFile);
            Log.e(TAG, "httpPost: 333333333333" );
            /* 設置每次寫入1024bytes */
            int bufferSize = 1024;
            byte[] buffer = new byte[bufferSize];
            int length = -1;
            /* 從文件讀取數據至緩衝區 */
            while ((length = fStream.read(buffer)) != -1) {
                /* 將資料寫入DataOutputStream中 */
                ds.write(buffer, 0, length);
            }
            ds.writeBytes(end);
            ds.writeBytes(twoHyphens + boundary + twoHyphens + end);//結束

            fStream.close();
            ds.flush();
            /* 取得Response內容 */
            is = con.getInputStream();
            int ch;
            StringBuffer b = new StringBuffer();
            while ((ch = is.read()) != -1) {
                b.append((char) ch);
            }
            /* 將Response顯示於Dialog */
            Log.e(TAG, "httpPost: ------上傳成功-----");
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "httpPost: ======----"+e );
            Log.e(TAG, "httpPost: --------上傳失敗----" );
        }finally {
            /* 關閉DataOutputStream */
            if(ds!=null){
                try {
                    ds.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (con != null) {
                con.disconnect();
            }
        }
    }
    public static void handleSSLHandshake() {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }

                @Override
                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            }};

            SSLContext sc = SSLContext.getInstance("TLS");
            // trustAllCerts信任所有的證書
            sc.init(null, trustAllCerts, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
        } catch (Exception ignored) {
        }
}
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • SQL代碼: SELECT t.* FROM pt_org_info t START WITH t.id = 1 CONNECT BY t.par_id = PRIOR t.id ORDER SIBLINGS BY t.id; 效果圖: ...
  • 此文章對開放數據介面 API 之「全國天氣預報信息數據 API」進行了功能介紹、使用場景介紹以及調用方法的說明,供用戶在使用數據介面時參考之用,並對實戰開發進行了視頻演示。 ...
  • 連接資料庫: try { SqlConnection conn = new SqlConnection(); conn.ConnectionString = "Data Source = (local); Initial Catalog =manage; Integrated Security = ...
  • 本文是對Hadoop2.2.0版本的MapReduce進行詳細講解。請大家要註意版本,因為Hadoop的不同版本,源碼可能是不同的。 以下是本文的大綱: ...
  • 摘要:第一階段:Linux課程講解Linux基礎操作,講的是在命令行下進行文件系統的操作,這是Hadoop學習的基礎,後面的所有視頻都是基於linux操作的。鑒於很多學員沒有linux基礎,特增加該內容,保證零linux基礎入門。如果你從沒有使用過linux,別擔心,本節內容可以讓你入門。Linux ...
  • 第一個函數是計算平面坐標系下,兩點的距離,就是 如果用於計算地球兩點的距離,帶入的參數是角度(0-360度),則計算的單位也是相差的角度,用此角度計算距離不准。緯度距離約111km每度,經度距離在赤道平面上是111km每度,隨緯度的升高逐漸降低為0。 第二個函數是計算球面距離的公式,傳入的參數是經緯 ...
  • Zeus Group 要編寫應用程式“Android”的程式代碼,需要使用特殊的開發環境。 自從創建用於編程的操作系統以來,已經使用了Eclipse和IntelliJ IDEA產品。 為此,已發佈插件,專門用於為Android創建應用程式。 但是,在從Google發佈官方開發環境之後 - Andro ...
  • 1. 概述 最近在做一些關於人臉識別的項目,需要用到 Android 相機的預覽功能。網上查閱相關資料後,發現 Android 5.0 及以後的版本中,原有的 Camera API 已經被 Camera2 API 所取代。 全新的 Camera2 在 Camera 的基礎上進行了改造,大幅提升了 A ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...