安卓调接口时不要在session里面存取数据!!!

安卓调接口时不要在session里面存取数据!!!

安卓调接口时不要在session里面存取数据!!!

这个真得坑。。。。。这个坑浪费了我大半天的时间

在写接口的时候,刚开始是按照正常的套路走的,中间用到一个值,我就直接存在session里面了,然后下一个接口再取出来用的,这个套路在ios端是正常的,但是到了安卓调用这个接口的时候,在取session值的时候,使用​​session.getAttribute("orderNum")​​,一直报空指针。

查了一下之后网上有人说安卓保持会话连接需要在安卓的请求头部加上sessionId:

OkHttpUtils.post()
.url(ServerConfig.REMOTE_BASE_URL + ServerConfig.REGISTER_URL)
.addHeader("Cookie", "JSESSIONID=" + sessionId)
.addParams("account", account)
.addParams("phoneCode", phoneCode)
.addParams("password", password)
.build()
.execute(new StringCallback() {

里面的sessionId是后台存session值的接口里,返回给安卓的,安卓在下次访问别的接口,需要用到session里的值的时候,将这个sessionId添加到头部里面,然后后台就可以保持会话连接了,但是我试了之后,并不好使,还是报空指针。

我还以为是sessionId没有传过来呢,然后在后台获取Cookie看了一下:

Cookie[] cookies = request.getCookies();
String sessionId = "";
for (Cookie cookie : cookies) {
switch(cookie.getName()){
case "JSESSIONID":
sessionId = cookie.getValue();
System.out.println("sessionId :" + sessionId );
break;
default:
break;
}
}

可以看到,后天确实获取到sessionId了,并且就是返回给安卓端的sessionId

到这里可能小伙伴都知道接下来该怎么做了,就是根据sessionId获取session的内容了,但是。。。。。

我使用​​如何根据sessionID获取session解决方案​​这位大佬的方法试了一下,仍然报空指针???????

感觉这个session仿佛在针对我?????

sessionId都有了,​​session.getAttribute("orderNum")​​怎么还是空指针呢????

好吧,那就看一下session里面的内容都是什么吧,于是遍历了一下session的内容:

//获取session
//HttpSession session = request.getSession();
MySessionContext myc= MySessionContext.getInstance();
HttpSession session = myc.getSession(sessionId);
// 获取session中所有的键值
Enumeration<?> enumeration = session.getAttributeNames();
// 遍历enumeration中的
while (enumeration.hasMoreElements()) {
// 获取session键值
String name = enumeration.nextElement().toString();
// 根据键值取session中的值
Object value = session.getAttribute(name);
// 打印结果
System.out.println("*******" + name + " = " + value + "********");
}

神奇的事情出现了,竟然什么都没有打印,意不意外????惊不惊喜?????

----------------------------------------------------------------------分割线-------------------------------------------------------------

在我写这篇总结的时候,发现我好像犯了一个错误,就是我在根据sessionId取session的时候,并没有提前将sessionId和session存到MySessionContext 里面,这一步应该是在将sessionId返回给安卓的接口里面,将这个session保存下来,然后在另一个接口里面根据sessionId获取session,但是我纳闷的是,这个对应的sessionId不存在的时候,​​HttpSession session = myc.getSession(sessionId);​​​里面的session应该为​​null​​了,下面这一句应该抛出空指针的异常

// 获取session中所有的键值
Enumeration<?> enumeration = session.getAttributeNames();

因为在MySessionContext 的getSession方法里,使用根据HashMap的key获取value的,当key不存在时,返回​​null​​。

public synchronized HttpSession getSession(String sessionID) {  
if (sessionID == null) {
return null;
}
return sessionMap.get(sessionID);
}

有兴趣的小伙伴可以试一下,在登录成功之后,或者是存session的时候,先初始化MySessionContext ,然后将sessionId对应的session存到MySessionContext 里面,然后在另一个方法里面调用getSession。

由于这个接口参数比较复杂,使用postman测试太麻烦了,这半天都是安卓配合我测试的,已经被这个空指针折腾了大半天了,刚开始安卓那边说我的接口有问题,我说是安卓那边的问题,前后端分离之后 大家都会甩锅了。因为这两个接口,ios那边调用是正常的,直接就是普通的session的存取,所以第一反应肯定不是我的锅。

谁的锅的问题就纠缠不清了,对于程序猿来说,写bug,改bug就是自己的工作,所以不用纠结谁的锅了,有这点纠结的时间能找到解决办法就好了。

----------------------------------------------------------------------分割线-----------------------------------------------------------

在试了几次之后,我看着打印的信息,还是这一句的空指针问题​​session.getAttribute("orderNum")​​。

然后我试了一下,在取session值的方法里面,直接获取session看看

String jsessionId = request.getSession().getId();
System.out.println("jsessionId :" + jsessionId );

发现这个jsessionId跟Cookie里面的sessionId竟然是不一样的,难怪我第一次直接在session里面获取orderNum报空指针了,我看到别的博客里面说安卓访问不同的接口时,sessionId是不一样的,在我告诉安卓在请求头部将sessionId加上去之后,还是不行。这里打印之后真的看到了sessionId是不一样的了。

直接去session不行,根据sessionId获取session也不行,那就没招了吗????

其实并不是。。。。。我一直在纠结这个session的问题,就没有想到别的方法试试,直到安卓的同事问我一句,你用session干嘛了?不用不行吗?你用session存取值不行的话,那就先把存进session里的orderNum 的值给我返回来,然后我请求的时候直接带过去不就好了吗?

这句话真的点醒了我,就是啊!直接返回,然后再带过来,不是分分钟的事吗,这么so easy !!!!

然后还等什么,开始改,分分钟,去掉之前关于session的相关代码,直接返回,然后获取,然后就好了!

到这里虽然这个bug解决了,但是关于安卓调用接口里session存取值的问题还是没明白。

有兴趣的小伙伴可以试一下中间分割线里面的内容,先把sessionId和session存起来,然后让安卓将sessionId加在请求的头部,再根据sessionId获取session,我想这样应该没问题。