第五节主要是介绍后端服务器、前端APP,及在Mysql数据库中,用户的信息存储。
Android移动端的登录/注册/主界面:
(在主界面中,点击四个按钮,可分别生成五言绝句、五言律诗、七言绝句、七言律诗)
一、封装数据库连接类:
import pymysql
# 封装数据库连接类
class SunckSql():
def __init__(self,host , user, passwd , dbName):
self.host = host # 主机IP地址
self.user = user # 登陆数据库的用户名
self.passwd = passwd # 密码
self.dbName = dbName #所用数据库名称
def connet(self): # 连接MySQL数据库
self.db = pymysql.connect(self.host,self.user,self.passwd,self.dbName)
self.cursor = self.db.cursor()
def close(self): # 关闭连接
self.cursor.close()
self.db.close()
def get_one(self , sql): # 查询表中满足条件的下一条信息
res = None
try:
self.connet()
self.cursor.execute(sql) # 执行sql语句
res =self.cursor.fetchone()
self.close()
except:
print("查询失败!")
return res
def get_all(self ,sql):# 查询表中满足条件的所有信息
res = None
try:
self.connet()
#使用连接对象获得一个cursor对象,接下来,我们会使用cursor提供的方法
self.cursor.execute(sql)
res= self.cursor.fetchall()
self.close()
except:
print("查询失败!")
return res
def insert(self , sql):
return self.__edit(sql)
def update(self , sql):
return self.__edit(sql)
def delete(self , sql):
return self.__edit(sql)
def __edit(self, sql):
res = None
try:
self.connet()
res = self.cursor.execute(sql)
#执行完插入或删除或修改操作后,需要调用一下conn.commit()方法进行提交.这样,数据才会真正保 存在数据库中
self.db.commit()
self.close()
except:
print("事务提交失败!")
self.db.rollback()
return res
二、应用Flask框架,实现的服务器端:
from flask import Flask,request
from SQL_operator import SunckSql
import config
import main
app = Flask(__name__)
global Num,JueLv,Keyword
global s ,ipv4
ipv4 ='192.168.43.244' # 动态IP,根据本地局域网,自己设定
s = SunckSql(ipv4 ,'root','123456','practice') # practice 数据库名称,密码
# 注册:
@app.route("/LoginDemo/RegisterServlet/",methods=["GET"])
#/LoginDemo/RegisterServlet/ Android端的路径名
def register_servlet():
print(request.form)
print(request.args)
# print(request.args['userAccount'] + "\n" + request.args['userPassword']+'\n'+
# request.args['userName']+'\n'+request.args['userSex']+'\n'+request.args['userBirth'])
account = request.args['userAccount']
password = request.args['userPassword']
uname = request.args['userName']
print(uname)
sex = request.args['userSex']
birth = request.args['userBirth']
sql = "Insert into userinforma VALUES(" + account+","+password+",'"+uname+"','"+ sex+"','"+birth+"')"
print(sql)
result = s.insert(sql)
if result != None:
return "注册成功"
else:
return "注册失败"
# 登陆
@app.route("/LoginDemo/LoginServlet/",methods=["GET" ])
def login_servlet():
print(request.args)
print(request.args['userAccount'] + " "+ request.args['userPassword'])
account = request.args['userAccount']
password = request.args['userPassword']
# s = SunckSql("127.0.0.1", 'root','123456','practice')
sql = "Select userAccount from userinforma where userAccount =" + account+" and userPassword= "+ password
print(sql)
result = s.get_one(sql)
if result != None:
return "登陆成功"
else:
return "登陆失败"
# 传送 诗类型 几言 - 绝句/律诗 + 关键词
@app.route("/LoginDemo/",methods=["GET"])
def poem_kinds():
# print(request.args)
# print(request.args['userNum'] + " "+ request.args['userJueLv']+ " " + request.args['userKeyword'])
# 根据用户输入得到 五/七言+ 绝句/律诗 + 关键词
Num = request.args['userNum']
JueLv= request.args['userJueLv']
Keyword = request.args['userKeyword']
# return num,juelv,keyword
poems = main.Main.Finalsummary(Num, JueLv, Keyword)
# print('\n'+poems)
return poems
if __name__ == "__main__":
app.run(host= ipv4, port=8080)
三、Android端界面,登陆+注册+诗歌内容展示:
public class MainActivity extends AppCompatActivity{
EditText account;
EditText password;
Button login;
Button register;
Button user_list;
@Override
protected void onCreate(Bundle savedInstanceState) {
//去掉顶部标题
getSupportActionBar().hide();
//去掉最上面时间、电量等
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.KITKAT) {
//透明状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// 透明导航栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
account=(EditText)findViewById(R.id.account);//输入账户
password=(EditText)findViewById(R.id.password);//输入密码
login=(Button)findViewById(R.id.login); // 登陆
register=(Button)findViewById(R.id.register); //注册
login.getBackground().setAlpha(90); //0~255透明度值
register.getBackground().setAlpha(90);
// user_list=(Button)findViewById(R.id.user_list); // 用户信息
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!(account.getText().toString().isEmpty())
&& !(password.getText().toString().isEmpty())) {
login(account.getText().toString(), password.getText().toString());
// Toast.makeText(MainActivity.this,"登陆成功" ,Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "账号、密码都不能为空!", Toast.LENGTH_SHORT).show();
}
}
});
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 进入注册界面
Intent intent = new Intent(MainActivity.this,Register.class);
startActivity(intent);
}
});
}
private void login(String account, String password) {
String registerUrlStr = Constant.URL_Login + "/?userAccount=" + account + "&userPassword=" + password;
// Toast.makeText(MainActivity.this,registerUrlStr,Toast.LENGTH_SHORT).show();
Log.d("JSON","指令:"+registerUrlStr);
Login_AsyncTask login_asyncTask =new Login_AsyncTask();
login_asyncTask.execute(registerUrlStr);
}
class Login_AsyncTask extends AsyncTask<String, Integer, String> {
public Login_AsyncTask() {
Log.d("JSON","验证前");
}
@Override
public void onPreExecute() {
Log.w("JSON", "开始验证.........");
}
/**
* @param params 这里的params是一个数组,即AsyncTask在激活运行是调用execute()方法传入的参数
*/
@Override
public String doInBackground(String... params) {
HttpURLConnection connection = null;
StringBuilder response = new StringBuilder();
try {
URL url = new URL(params[0]); // 声明一个URL
connection = (HttpURLConnection) url.openConnection(); // 打开该URL连接
connection.setRequestMethod("GET"); // 设置请求方法,“POST或GET”,我们这里用GET,在说到POST的时候再用POST
connection.setConnectTimeout(80000); // 设置连接建立的超时时间
connection.setReadTimeout(80000); // 设置网络报文收发超时时间
BufferedReader reader =new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.d("JSON",response.toString()+"dsdfasfdfedfrwfrwf");
return response.toString(); // 这里返回的结果就作为onPostExecute方法的入参
}
@Override
protected void onProgressUpdate(Integer... values) {
// 如果在doInBackground方法,那么就会立刻执行本方法
// 本方法在UI线程中执行,可以更新UI元素,典型的就是更新进度条进度,一般是在下载时候使用
}
/**
* 运行在UI线程中,所以可以直接操作UI元素
* @param s
*/
@Override
protected void onPostExecute(String s) {
Log.d("JSON",s); //打印服务器返回标签
// Toast.makeText(MainActivity.this, s , Toast.LENGTH_SHORT).show();
//flag=true;
switch (s){
//判断返回的状态码,并把对应的说明显示在UI
case "登陆成功":
Toast.makeText(MainActivity.this,"登录成功",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(MainActivity.this,WritePoem.class);
startActivity(intent);
break;
default:
Toast.makeText(MainActivity.this,"登陆失败,账号或密码错误",Toast.LENGTH_SHORT).show();
break;
}
Log.d("JSON","验证后");
}
}
}
在Android端代码比较多,这里只展示了主界面的代码。
到此,整个项目介绍完了。项目的代码量有点多,可能感觉有点乱。以后有时间的话,我会把每个模块分开,建立一个个小的demo,来讲解。