Flask初體驗——搭建Android登錄后端

前言

? Flask是一個使用Python編寫的輕量級 Web 應用框架,對于像我這種想偷懶,不想自己從頭學后端的人來說是再合適不過了,為了使用Flask,我在十一月份就已經開始了學習Flask必備的Python知識。

明確目標

? 首先要明確目標,我要做的是在客戶端輸入用戶名密碼,然后選擇登錄還是注冊,在服務器端進行檢驗,并存儲數據到服務器端的數據庫(為了簡便使用SQLite),并且返回Response消息回客戶端,客戶端再根據返回的Response消息進行相應的動作。由于在大一的時候用C語言做過一個京東購物管理系統,里面涉及了在本地登錄,所以我對登錄頁面的邏輯還算是輕車熟路了。

首先寫Android端邏輯

? 首先需要在APP端構造一個簡單的登錄界面,只需要兩個EditText和兩個按鈕就行了。如圖所示

登陸界面

? 然后寫代碼從兩個輸入框中將用戶輸入的用戶名和密碼提取出來。

@Override
    public void onClick(View v)
    {
        String userName = userNameEdit.getText().toString();
        String passWord = passWordEdit.getText().toString();
        if(userName.equals("")||passWord.equals(""))
        {
            showWarnSweetDialog("賬號密碼不能為空");
            return;
        }
        switch (v.getId())
        {
            case R.id.log_Button:
                String url = "http://192.168.253.1:5000/user";/*在此處改變你的服務器地址*/
                getCheckFromServer(url,userName,passWord);
                break;
            case R.id.Sign_Button:
                String url2 = "http://192.168.253.1:5000/register";/*在此處改變你的服務器地址*/
                registeNameWordToServer(url2,userName,passWord);
                break;
        }
    }

? 有一點重要的是要判斷不為空,由于這個應用不牽涉到大規模使用,所以不對密碼安全性進行限制。

? 接下來先寫注冊模塊,注冊模塊由registeNameWordToServer()函數來實現,這個模塊功能就是將用戶名密碼發送到url對應的服務器地址。在網絡方面為了簡便,使用了一個OKHttp的開源網絡框架。

 private void registeNameWordToServer(String url,final String userName,String passWord)
    {
        OkHttpClient client = new OkHttpClient();
        FormBody.Builder formBuilder = new FormBody.Builder();
        formBuilder.add("username", userName);
        formBuilder.add("password", passWord);
        Request request = new Request.Builder().url(url).post(formBuilder.build()).build();
        Call call = client.newCall(request);
        call.enqueue(new Callback()
        {
            @Override
            public void onFailure(Call call, IOException e)
            {
                runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        showWarnSweetDialog("服務器錯誤");
                    }
                });
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException
            {
                final String res = response.body().string();
                runOnUiThread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        if (res.equals("0"))
                        {
                            showWarnSweetDialog("該用戶名已被注冊");
                        }
                        else
                        {
                            showSuccessSweetDialog(res);
                            sharedPreferences = getSharedPreferences("UserIDAndPassword", MODE_PRIVATE);
                            SharedPreferences.Editor editor = sharedPreferences.edit();
                            editor.putString("username", userName);
                            editor.apply();
                        }

                    }
                });
            }
        });

    }

只需要調用Request的post方法就能夠進行post動作。在Call里收到服務器的返回消息,重寫CallBack接口,寫出成功響應和失敗響應的邏輯。在接口中由于OkHttp已經封裝了子線程操作,所以這是在子線程中的動作,如果需要彈出對話框需要返回UI線程。

接下來的登錄模塊跟注冊模塊大同小異。

服務器端邏輯

? 服務器端要用到Flask,所以當然首先創建一個Flask項目,由于我用的IDE是JetBrain的PyCharm,創建Flask項目非常方便。本來我以為服務器端會很難,還專門買了一本Flask的書,結果還沒看幾頁的知識就完全夠用了。先上代碼:

from flask import Flask
from flask import make_response
from flask import request
from flask.ext.script import Manager
import os
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
basedir=os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///'+os.path.join(basedir,'userConfigBase.sqlite')
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN']=True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True
userdb=SQLAlchemy(app)
manager=Manager(app)
@app.route('/')
def test():
    return '服務器正常運行'

class userInfoTable(userdb.Model):
    __tablename__='userInfo'
    id=userdb.Column(userdb.Integer,primary_key=True)
    username=userdb.Column(userdb.String,unique=True)
    password=userdb.Column(userdb.String)

    def __repr__(self):
        return 'table name is '+self.username

#此方法處理用戶登錄 返回碼為0無注冊 返回碼為1密碼錯誤
@app.route('/user',methods=['POST'])
def check_user():
    haveregisted = userInfoTable.query.filter_by(username=request.form['username']).all()
    if haveregisted.__len__() is not 0: # 判斷是否已被注冊
        passwordRight = userInfoTable.query.filter_by(username=request.form['username'],password=request.form['password']).all()
        if passwordRight.__len__() is not 0:
            return '登錄成功'
        else:
            return '1'
    else:
        return '0'


#此方法處理用戶注冊
@app.route('/register',methods=['POST'])
def register():
    userdb.create_all()
    haveregisted = userInfoTable.query.filter_by(username=request.form['username']).all()
    if haveregisted.__len__() is not 0: # 判斷是否已被注冊
        return '0'
    userInfo=userInfoTable(username=request.form['username'],password=request.form['password'])
    userdb.session.add(userInfo)
    userdb.session.commit()
    return '注冊成功'

if __name__ == '__main__':
    manager.run()


class userInfoTable(userdb.Model):
    __tablename__='userInfo'
    id=userdb.Column(userdb.Integer,primary_key=True)
    username=userdb.Column(userdb.String,unique=True)
    password=userdb.Column(userdb.String)

    def __repr__(self):
        return 'table name is '+self.username

? @app.route('/')為裝飾器,起作用就是在客戶端訪問“服務器地址/”是可以調用相應的函數。比如@app.route('/register',methods=['POST'])就是當訪問 "服務器地址/register"時調用的。

? Python使用SQLAlchemy操作數據庫很方便,幾句代碼就創建完畢了,一看就懂,當創建表時就要注意了,需要自己寫一個類來實現這個表里所需的列。這個類需要繼承自你的數據庫.Model,userdb.Column(userdb.String,unique=True)就相當于創建了一個String類型的不可重復的列,用來儲存用戶名在合適不過了。

? 接下來就要在函數里處理登錄注冊的邏輯,注冊邏輯是這樣的:取出Request中的username,將其作為關鍵字放進數據庫中搜索,若沒有,則將其用戶名和密碼都儲存下來,若已經存在了,則返回一個錯誤信號通知客戶端已經存在了。

? 登陸邏輯就更簡單了,只需要取出Request中的username,若數據庫中不存在,就通知用戶請先注冊,若存在但密碼不正確,則通知用戶密碼錯誤,若密碼正確,則返回正常信息。

總結

? 通過這次Flask的后端實踐,我深刻明白了一個道理,往往你認為難的東西,你真正去做了,往往會發現并沒有這么難。以前我總是把搭建服務器和Android網絡編程想的很難,其實真正去做了,并不是很難。而那些你認為很簡單那的東西,如果不考慮周到,往往會出岔子。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,791評論 6 545
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,795評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,943評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,057評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,773評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,106評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,082評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,282評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,793評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,507評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,741評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,220評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,929評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,325評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,661評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,482評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,702評論 2 380

推薦閱讀更多精彩內容