用volley 就是觉得可以简单不用序列化数据,用retrofit2 就是整合了.接口,数据的序列化.适合大点的项目管理
用retrofit2 写了一个新闻数据库的一个App ,要将以前用 volley写的 用户管理, 转到 retrofit2 ,新闻模块
就要求 retrofit2 发送 cookie 中保存的,session id 数据
Andorid app 中保存,cookie 的方式就是 用本地存储 sp,方式, 数据库网关用 node.js 做的web 服务器 ,开启sesson 支持实现 用户免登.现在我做的的这个 app 还没有转到 https ,所以还没有用到 okhttp3 拦截器的复杂功能.恰只使用 它的添加header ,的简单功能
- 我先摆个书袋子.
所谓 session id 就是,node.js web 端识别每次访问者的一种加密串,好像是上车后的"票根"或者说是,出门的"卡票",你每次登录同一个网址如果没有,保存这个"票" 下次,再来就没有办法证明你来过,所以这个"票根"
每次都是"新的" 如果你没有将你保存的"票根"提供给 web .识别.web 就不能知道你来没来过.下面web
就可以凭借 这个session id ,将后面登录,后的权限逻辑应用于你的请求.
简单的模式就是 ,你某一次访问web ,如果登录输入密码,如果你的app将此次web 给的 session id 串,
(这个串就是http head 中的 cookie id 数据, 保存下,存储在你本地的 sp ,中 )保存. 你下次app 登录
这个web 必需用使用它,也就是 加在你的http head 中
okhttp3 (是retrofit2 配合使用的)
.addHeader("Cookie", cookieStr)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
这里原来的有一个坑,就是使用了 header 而不是 addHeader ,
不知道是不是版本的问题.
volley 中
public String getBodyContentType() {
return "application/x-www-form-urlencoded";
}
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap localHashMap=new HashMap();
localHashMap.put("Cookie",user.get(mSessionManager.SESSION_ID));
return localHashMap;
}
-
volley 是一个很好的入门,
因为volley 使用的时候,你只用在一个"地方"定义完整的访问代码 -
retrofit2 作为一个框架,是很好的管理
你需要在不同的代码中将 ,访问接口,数据对象的序列化,请求,发送,等进行组装堆叠.
实际上原理很简单.但是为了将各个管理模块分开,布置的复杂度却增高了.不过
这为后期维护和升级提供了.空间.
.总的来说没有使用过的人,需要耐心来搞顺 retrofit2 的框架布置方式.这搞通了后
不论从数据上传,还是权限管理方便.都比 volley 便于管理.
- 江湖一点绝,说破不值钱!
有经验的人.一下就能找到位置.没经验的人.就要从头开始好好看看别人
已经写就的复杂纷繁的臃肿的逻辑代码.从中找到它.
//…
- node.js 服务器 的 接口定义
//测试
router.get('/News_test',(req,res,next)=>{
res.setHeader('Content-Type', 'text/palin; charset=utf-8');
console.log("进入测试");
let resultStr={}
if(req.session.hasOwnProperty("user")) {
console.log("session id:" + req.session.user.id);
resultStr={
success:"1",
message:"测试发送..."
}
res.send(JSON.stringify(resultStr));
console.log(JSON.stringify(resultStr));
}
});
- andorid app 端的定义.
API
定义
//…
//测试 Api 的定义
@GET("News_test")
Call<townNews>getTownNewsTest(
@Query("newsType_id") String newsType_id //需要修改
);
app 发送请求的定义
private void read_web_db() {
ApiInterface apiInterface= ApiClient
.getApiClient_cookie(user.get(mSessionManager.SESSION_ID))
.create(ApiInterface.class);
Call<townNews> call;
String keyword="";
call = apiInterface.getTownNewsTest(keyword);
call.enqueue(new Callback<townNews>() {
@Override
public void onResponse(Call<townNews> call, Response<townNews> response) {
}
@Override
public void onFailure(Call<townNews> call, Throwable t) {
}
});
}
public static Retrofit getApiClient_cookie(String cookieStr){
dataUrl=new DataUrl();
BASE_URL=dataUrl.getHostNewspath();
if(retrofit==null){
retrofit=new Retrofit.Builder().baseUrl(BASE_URL) //打包了 读取的 Url
.client(getClient(cookieStr) ) //将 cookie 发送
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
使用 拦截器 追加 cookie 信息
private static final long TIMOUT =5000 ;
private static OkHttpClient getClient(String cookieStr) {
OkHttpClient.Builder client = new OkHttpClient().newBuilder();
client.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
//提取本地 cookie id
if (StringUtils.isNotEmpty(cookieStr)) {//判断读取成功
return chain.proceed(
chain.request()
.newBuilder()
.addHeader("Cookie", cookieStr)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.build());
}
return chain.proceed(chain.request());
}
});
client.connectTimeout(TIMOUT, TimeUnit.MILLISECONDS);
client.writeTimeout(TIMOUT, TimeUnit.MILLISECONDS);
client.readTimeout(TIMOUT, TimeUnit.MILLISECONDS);
return client.build();
}
关于本地如何存储 cookie 到 sp
package com.jackmacc.townadmin.maninfo;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import com.jackmacc.townadmin.home_page;
import java.util.HashMap;
public class SessionManager {
SharedPreferences mSharedPreferences;//获取
public SharedPreferences.Editor mEditor;//存放
public Context mContext;
int PRIVATE_MODE=0;
private static final String PREF_NAME="LOGIN";
private static final String LOGIN="IS_LOGIN";
public static final String NAME="NAME";
public static final String EMAIL="EMAIL";
public static final String ID="ID";
public static final String SESSION_ID="SESSION_ID";
public SessionManager(Context context) {
this.mContext = context;
mSharedPreferences =
context.getSharedPreferences(PREF_NAME,PRIVATE_MODE); //获取
mEditor=mSharedPreferences.edit(); //得到
}
public void createSessiond(String name,String Email,String id){ //向 SP editor 定义充值
mEditor.putBoolean(LOGIN,true);
mEditor.putString(NAME,name);
mEditor.putString(EMAIL,Email);
mEditor.putString(ID,id);
mEditor.apply();
}
public void addSessionId(String sessionid){
mEditor.putString(SESSION_ID,sessionid);
mEditor.apply();
}
public boolean isLoggin(){ //查询是否登录过
return mSharedPreferences.getBoolean(LOGIN,false);
}
public void checkLogin(){
if(!this.isLoggin()){//效验登录
Intent i=new Intent(mContext, maninfoLoginActivity.class);
mContext.startActivity(i);
// ((PHP_HomeActivity)mContext).finish();
}
}
public HashMap<String,String> getUserDetail(){
HashMap<String,String> user=new HashMap<>();//一个存放 属性的实体
user.put(NAME,mSharedPreferences.getString(NAME,null));
user.put(EMAIL,mSharedPreferences.getString(EMAIL,null));
user.put(ID,mSharedPreferences.getString(ID,null));
user.put(SESSION_ID,mSharedPreferences.getString(SESSION_ID,null));
return user;
}
public void logout(){
mEditor.clear();//清除登录
mEditor.commit();
Intent i=new Intent(mContext, home_page.class);
mContext.startActivity(i);
// ((object)mContext).finish();
}
public void EditorClear() {
mEditor.clear();//清除登录
mEditor.commit();
}
}
使用方式:
// activity 类声明
static HashMap<String, String> user;
SessionManager mSessionManager; //cookie 管理模块
onCreate 使用
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_civ_friend_list);
mSessionManager = new SessionManager(this); //获取SR
mSessionManager.checkLogin(); //未登录被退回到登录....
//读取 session sp中 信息打包
user = mSessionManager.getUserDetail();