网络请求开始
前言
网络请求,我们得先知道网络请求的地址对吧,先来我们玩安卓看一下玩安卓开放api
问题
这里讲一下我自己使用玩安卓api实现的时候遇到的问题,主要问题就是登陆后cookies的存储
5.1 登录
https://www.wanandroid.com/user/login
方法:POST
参数:
username,password
登录后会在cookie中返回账号密码,只要在客户端做cookie持久化存储即可自动登录验证。
玩安卓的认证方式是采用cookies,所以就涉及到我们客户端如何存储cookies,然后现有flutter中有哪些能用的库方便我们操作
网络请求及cookies存储
首先网络请求我使用的是Dio
cookies存储使用的是:dio_cookie_manager
注意:由于在使用cookie_manager时如果采用的是持久化存储,就需要在本地一个目录保存cookies信息,但是如果只按照网上的方法,就是
dio.interceptors.add(CookieManager(PersistCookieJar(dir: "/cookies")));
这样来的话,在不同的平台上会有错误,错误信息就是,权限的问题,所以我猜测是填写的dir地址,在新建文件夹的时候没有权限,所以另外还需要使用一个库path_provider然后使用如下方式获取一个临时目录,就不会出现权限问题了
Directory tempDir = await getTemporaryDirectory();
cookiePath = tempDir.path;
再贴上ymal需要添加的依赖
dependencies:
# 网络请求
dio: ^3.0.0
dio_cookie_manager: 1.0.0
path_provider: ^1.3.0
网络请求讲解结束
状态管理开始
状态管理在项目中我使用的是provider
同时,为了保存用户的信息,和当前状态的信息,新建了三个model信息(userinfo,mytheme,profile),
也是通过json转model的方式来实现的,因为后面还需要将model保存到本地,采用了shared_preferences,需要将model转成json存到本地
userinfo.json
{
"username":"",
"pwd":"",
"islogin":false
}
mytheme.json(这里只设置了app的主题颜色)
{
"themecolor":0
}
profile.json
{
"userinfo":"$userinfo",
"theme":"$mytheme"
}
运行:
flutter packages pub run json_model
生成model成功之后,我们添加需要使用到依赖
dependencies:
# 数据管理层
provider: 3.0.0+1
dev_dependencies:
shared_preferences: ^0.5.3
在common下新建一个store.dart文件
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/material.dart';
import 'package:wanandroid_client_app/models/index.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
class Store{
static String cookiePath;
static Profile profile;
static ColorSwatch themeColor;
static SharedPreferences sharedPreferences;
static dynamic init({context,child}) async{
// 初始化获取本地数据
sharedPreferences = await SharedPreferences.getInstance();
// 获取cookie保存的目录
Directory tempDir = await getTemporaryDirectory();
cookiePath = tempDir.path;
print(cookiePath);
// 通过sharedPreferences获取本地app配置
if(sharedPreferences.get("profile")==null){
// 说明本地没有配置,一般是第一次进入app,我们就新建配置信息
profile = Profile();
Userinfo userInfo = Userinfo();
// 设置用户名密码是空字符串
userInfo.username="";
userInfo.pwd="";
// 设置是否有用户登录为否
userInfo.islogin = false;
profile.userinfo = userInfo;
Mytheme mytheme = Mytheme();
// 设置当前app的颜色默认为样式数组中的第一个
mytheme.themecolor = themeColors[0].value;
themeColor = themeColors[0];
profile.theme = mytheme;
// 调用save方法,保存app配置到本地
save();
}else{
// 如果不为空,说明我们之前保存过设置到本地,因为保存时是保存的json格式,我们需要转换为对象
profile = Profile.fromJson(jsonDecode(sharedPreferences.get("profile")));
}
print("初始化数据为");
print(jsonDecode(sharedPreferences.get("profile")));
// 根据themecolor判断当前是哪一个color
for(int i=0;i
if(themeColors[i].value==profile.theme.themecolor){
themeColor = themeColors[i];
break;
}
}
}
//保存数据到本地,将配置对象转成json保存
static save(){
sharedPreferences.setString("profile", jsonEncode(profile.toJson()));
}
}
// 创建一个配置文件管理通知类
class ProfileNotifier with ChangeNotifier{
Profile get profile => Store.profile;
@override
void notifyListeners() {
// 调用save方法,将新的配置信息保存到本地
Store.save();
super.notifyListeners();
}
}
// 用户信息管理通知类
class UserInfoNotifier extends ProfileNotifier{
Userinfo get userinfo => profile.userinfo;
// 设置用户信息,比如退出登录或者登陆时
set setUserinfo(newuserinfo){
profile.userinfo = newuserinfo;
notifyListeners();
}
}
// 主题颜色配置表
const List themeColors = [
Colors.blue,
Colors.deepOrange,
Colors.green,
Colors.purple,
Colors.pink,
Colors.amber
];
// 主体颜色修改通知类
class ThemeNotifier extends ProfileNotifier{
ColorSwatch get themecolor =>Store.themeColor;
set setThemeColor(ColorSwatch newcolor){
Store.themeColor = newcolor;
profile.theme.themecolor = Store.themeColor.value;
notifyListeners();
}
}
网络请求文件创建
在service目录下新建net.dart
import 'package:dio/dio.dart';
import 'package:wanandroid_client_app/models/index.dart';
import 'dart:math';
import 'package:wanandroid_client_app/common/static_info.dart';
import 'package:wanandroid_client_app/common/store.dart';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
const String login = "user/login";
const String register = "user/register";
const String logout = "user/logout/json";
const String banner = "banner/json";
const String tree = "tree/json";
const String nav = "navi/json";
const String projectfl = "project/tree/json";
const String projectList = "project/list/PAGE/json?cid=CID";
const String tixiList = "article/list/PAGE/json?cid=CID";
const String gzh = "wxarticle/chapters/json";
const String gzhList = "wxarticle/list/CID/PAGE/json";
const String collectList = "lg/collect/list/PAGE/json";
String article = "article/list/pageIndex/json";
String collect = "lg/collect/Index/json";
String uncollect = "lg/uncollect_originId/Index/json";
//获取请求对象
Dio getDio() {
BaseOptions baseOptions = BaseOptions(
baseUrl: "https://www.wanandroid.com/",
);
Dio dio = Dio(baseOptions);
// 添加cookie管理
// if(Store.profile.userinfo.islogin){
//
// }
dio.interceptors.add(CookieManager(PersistCookieJar(dir: Store.cookiePath)));
dio.interceptors.add(LogInterceptor(responseBody: false)); //开启请求日志
return dio;
}
//用户登录
dynamic mylogin(String username, String pwd) async {
Map queryParameters = {"username": username, "password": pwd};
Dio dio = getDio();
Response response = await dio.post(login, queryParameters: queryParameters);
Map res = response.data;
return BaseResponse.fromJson(res);
}
//获取首页banner
Future> getBanner() async {
Dio dio = getDio();
Response response = await dio.get(banner);
Map res = response.data;
BaseListResponse baseListResponse = BaseListResponse.fromJson(res);
List banners = List();
if (baseListResponse.errorCode == 0) {
// 说明获取数据没有错误
for (int i = 0; i < baseListResponse.data.length; i++) {
banners.add(Banner.fromJson(baseListResponse.data[i]));
}
}
return banners;
}
//获取首页文章
Future getArticle(int index)async{
Dio dio = getDio();
String newarticle = article.replaceAll("pageIndex", index.toString());
Response response = await dio.get(newarticle);
Map res = response.data;
BaseResponse baseListResponse = BaseResponse.fromJson(res);
Page page = Page.fromJson(baseListResponse.data);
for(int i=0;i
page.datas[i].shareUser = Random().nextInt(2)==1?StaticInfo.manIcon.replaceAll("Index", Random().nextInt(50).toString()):StaticInfo.womanIcon.replaceAll("Index", Random().nextInt(50).toString());
}
return page;
}
//收藏文章
Future collectArticle(int index)async{
Dio dio = getDio();
String collectUrl = collect.replaceAll("Index", index.toString());
Response response = await dio.post(collectUrl);
Map res = response.data;
BaseResponse baseResponse = BaseResponse.fromJson(res);
return baseResponse.errorCode;
}
//取消收藏文章
Future unCollectArticle(int index)async{
Dio dio = getDio();
String uncollectUrl = uncollect.replaceAll("Index", index.toString());
Response response = await dio.post(uncollectUrl);
Map res = response.data;
BaseResponse baseResponse = BaseResponse.fromJson(res);
return baseResponse.errorCode;
}
获取体系分类
Future> getTreeJson()async{
List txouter = List();
Dio dio = getDio();
Response response = await dio.get(tree);
Map res = response.data;
TreeResponse treeResponse = TreeResponse.fromJson(res);
if(treeResponse.errorCode==0){
txouter = treeResponse.data;
}
return txouter;
}
//获取导航数据
Future> getNavJson() async{
List navouters = List();
Dio dio = getDio();
Response response = await dio.get(nav);
Map res = response.data;
NavResponse navResponse = NavResponse.fromJson(res);
if(navResponse.errorCode==0){
navouters = navResponse.data;
}
return navouters;
}
//获取项目的分类
Future> getProjectFl() async{
List projectfls = List();
Dio dio = getDio();
Response response = await dio.get(projectfl);
Map res = response.data;
ProjectReponse projectReponse = ProjectReponse.fromJson(res);
if(projectReponse.errorCode==0){
projectfls = projectReponse.data;
}
return projectfls;
}
//获取项目列表数据
Future> getProjectList(int page,int cid) async{
List projectAllOuterChild = List();
ProjectAllOuter projectAllOuter;
Dio dio = getDio();
Response response = await dio.get(projectList.replaceAll("PAGE", page.toString()).replaceAll("CID", cid.toString()));
Map res = response.data;
ProjectAllResponse projectAllResponse = ProjectAllResponse.fromJson(res);
if(projectAllResponse.errorCode==0){
projectAllOuter = projectAllResponse.data;
projectAllOuterChild = projectAllOuter.datas;
}
return projectAllOuterChild;
}
//获取体系列表数据
Future> getTixiList(int page,int cid) async{
List projectAllOuterChild = List();
ProjectAllOuter projectAllOuter;
Dio dio = getDio();
Response response = await dio.get(tixiList.replaceAll("PAGE", page.toString()).replaceAll("CID", cid.toString()));
Map res = response.data;
ProjectAllResponse projectAllResponse = ProjectAllResponse.fromJson(res);
if(projectAllResponse.errorCode==0){
projectAllOuter = projectAllResponse.data;
projectAllOuterChild = projectAllOuter.datas;
}
return projectAllOuterChild;
}
//获取公众号信息
Future> getGzh() async{
List gzhChild = List();
Dio dio = getDio();
Response response = await dio.get(gzh);
Map res = response.data;
GzhResponse gzhResponse = GzhResponse.fromJson(res);
if(gzhResponse.errorCode==0){
gzhChild = gzhResponse.data;
}
return gzhChild;
}
//获取公众号文章数据
Future> getGzhList(int page,int cid) async{
List projectAllOuterChild = List();
ProjectAllOuter projectAllOuter;
Dio dio = getDio();
Response response = await dio.get(gzhList.replaceAll("PAGE", page.toString()).replaceAll("CID", cid.toString()));
Map res = response.data;
ProjectAllResponse projectAllResponse = ProjectAllResponse.fromJson(res);
if(projectAllResponse.errorCode==0){
projectAllOuter = projectAllResponse.data;
projectAllOuterChild = projectAllOuter.datas;
}
return projectAllOuterChild;
}
//查看我的收藏列表
Future getCollectList(int page) async{
Dio dio = getDio();
Response response = await dio.get(collectList.replaceAll("PAGE", page.toString()));
Map res = response.data;
MyCollectReponse myCollectReponse = MyCollectReponse.fromJson(res);
if(myCollectReponse.errorCode==0){
return myCollectReponse.data;
}
return null;
}