安卓登入以及會話保持的解決方案

來源:互聯網
上載者:User

標籤:property   使用者登入   app   沒有   ext   pos   rom   pass   htm   

項目做到一半技術經理辭職了,留個爛攤子。web基本已做完,安卓的app要新寫,項目開發完做個總結,這東西已經是好久前做的了。

登入介面很快就寫好了,登入成功後使用者資訊是緩衝再session當中的

 /**     * 使用者登入     *     * @param user     * @return     */    @RequestMapping(value = "doLogin")    @ResponseBody    public Map doLogin(User user, HttpServletRequest request) {        Map result = Maps.newHashMap();        try {            LoginResult flag = FrontUserUtils.doLogin(user, request);            if (flag == LoginResult.登入成功) {                Map<String, Object> map = new HashMap<>();                String[] propertys = new String[]{"name", "photo", "singleId"};                for (String property : propertys) {                    map.put(property, Reflections.invokeGetter(FrontUserUtils.getUserBySession(), property));                }                result.put("flag", 1);                result.put("user", map);                return result;            } else if (flag == LoginResult.使用者被鎖定) {                result.put("flag", 0);                result.put("msg", "使用者被鎖定,請聯絡管理員!");                return result;            } else if (flag == LoginResult.登入失敗) {                result.put("flag", 0);                result.put("msg", "帳號或密碼錯誤!");                return result;            }        } catch (Exception e) {            result.put("flag", 0);            result.put("msg", "操作失敗!");            e.printStackTrace();        }        return result;    }
 /

 

但是登入成功後,再調用其他需要擷取登入使用者資訊的時候的時候發現在session中沒有,不對啊,明明自已用瀏覽器測試是OK的啊,我自己補不瞭解嘛,

技術經理也跑了,不知道怎麼回事啊、咋整,我去問安卓,他也不懂啊,我也走吧。

 

然後debug測試吧,用瀏覽器不這樣啊,session是同一個呐。測試一下,在後台列印一下sessionid:

瀏覽器提供者:

類比安卓提供者:

每次都產生了新的session,這麼搞不行啊,每次請求都產生新session,我怎麼緩衝你登入使用者的資訊啊。

 

然後就想辦法解決啊 ,想來想去想了兩個方案

方案1:自訂身份識別方式(token),類似自己類比session

  再使用者登入以後,在系統內產生一個唯一的身份標識,並將此標識返回給用戶端。身份標識儲存15天,如果使用者,在其他終端登入,或者15天逾時在伺服器沒有業務,將通知終端會話逾時,重新登入。

 

  後台代碼就不貼了,使用的uuid產生的一個字串,作為使用者的登入標識,將使用者資訊寫入緩衝,類似key :user這種方式儲存。

 

         使用者請求其他介面的時候,會被我的一個攔截器攔截,如果發現根據字串查詢使用者查詢不到,就會將使用者剔除系統。

攔截器:

public class LoginInterceptor implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {        User user = FrontUserUtils.getUser();        if (user == null || user.getId() == null || user.getId().equals("")) {            returnJson(httpServletResponse);            return false;        } else {            return true;        }    }    @Override    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {    }    @Override    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {        e.notifyAll();    }    private void returnJson(HttpServletResponse response) throws Exception {        PrintWriter writer = null;        response.setCharacterEncoding("UTF-8");        response.setContentType("text/html; charset=utf-8");        try {            Map map = new HashMap();            map.put("flag", 0);            map.put("msg", "登陸會話已經到期,請重新登陸!");            JSONObject jsonObject = JSONObject.fromObject(map);            writer = response.getWriter();            writer.print(jsonObject);        } catch (IOException e) {        } finally {            if (writer != null)                writer.close();        }    }}

這樣寫,犧牲掉了一部分系統效能,來實現安卓與伺服器之間的長串連,因為基本攔截了所有的介面,每次都判斷是否登入,或者登入逾時。

 

 

 

方案2:還是使用sessionId,其實兩種方式都差不多,不過我還是推薦這種,第一種的花同一時間使用者太多,session過多,可能導致其他的問題。

 

web瀏覽器保持會話,是因為有session的存在,不同的伺服器在瀏覽器請求的時候會判斷是否為第一次請求,如果是第一次就回返回一個參數Set-Cookie,一般瀏覽器支援自己儲存這個資料,這個資料也是瀏覽器與伺服器保持會話的標識;

比如以百度為例:

再次請求相同的伺服器,瀏覽器會從cookie中取出這些這值,載入到瀏覽器的請求中去

 

瀏覽器如果不禁用cookie的話,瀏覽器就會將伺服器返回的資料儲存到cookie當中去,session與cookie不清楚的,去查資料吧。

 

 安卓的訪問方式

儘管安卓可以使用許多網路架構來進行訪問,但是我不是很瞭解呐,加上公司的安卓開發也不甚瞭解,

 

我覺得他是使用httpclient類似的方式來進行訪問的,我就謝了一個代碼類比了下安卓的請求,來擷取下伺服器返回的資料,看能不能擷取到 Set-Cookie;

 

public class MainActivity {    public static final String login_url="http://192.168.0.112:8080/login/doLogin?loginName=18866601116&password=123456zxc";    /**     * 安卓登入測試     * @param args     * @throws Exception     */    public static void main(String[] args) throws Exception {        URL url=new URL(login_url);        HttpURLConnection con=(HttpURLConnection) url.openConnection();        con.setRequestMethod("GET");        String cookieString=con.getHeaderField("Set-Cookie");        System.out.print(cookieString);    }}
//控制台輸出

 


  哎可以的。就讓安卓再第一次請求伺服器的時候將這個sessionid儲存下來吧,緩衝到手機,

然後請求背景時候,將儲存的cookie放在httpPost的請求當中,這樣訪問伺服器時,伺服器就會認為是同一個使用者了。也就是說保持了這個會話。

 

 

 

其實兩種方式的原理都差不多,如果有更好的方案,也可以跟我說,學習嘛。

 

安卓登入以及會話保持的解決方案

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.