我正在编写一个处理来自 android 客户端的请求的 servlet。每次我执行 HttpGet 时,servlet 都会根据HttpSession session = request.getSession(true);
.
问题是在每次请求时request.getSession(true);
总是分配一个新的会话值。即使请求来自同一个客户端,.getSession(true)
也只有在没有现有会话的情况下才会返回新的 sessionID。此外,在HttpSession
使用条件测试是否是新的时,if (session.isNew()) { // do something }
即使请求来自同一个客户端,它也始终为真。从浏览器执行相同的 URL 时一切正常。
如果会话永远不会被认为是旧的,我没有实用的方法来为我的会话设置租约(到期)时间。
代码,Android端:
private class LongRunningGetIO extends AsyncTask<String, Void, Object> {
private String URL = "http://server:port/path/servlet?";
private String functionType = "function=";
private String statement = "&statement=";
private String text = "&text=";
private String language = "&language=";
protected String getASCIIContentFromEntity(HttpEntity entity) throws IllegalStateException, IOException {
InputStream in = entity.getContent();
StringBuffer out = new StringBuffer();
int n = 1;
while (n > 0) {
byte[] b = new byte[4096];
n = in.read(b);
if (n > 0) out.append(new String(b, 0, n));
}
return out.toString();
}
@Override
protected Object doInBackground(String... params) {
String command = params[0];
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(URL + command);
System.out.println("Sent URL: " + URL + command);
String text = null;
try {
HttpResponse response = httpClient.execute(httpGet, localContext);
HttpEntity entity = response.getEntity();
text = getASCIIContentFromEntity(entity).toString();
} catch (Exception e) {
return e.getLocalizedMessage();
}
return text;
}
}
代码,Servlet端:
protected JSONObject validateID(HttpServletRequest request, JSONObject JSONObj, String lang) throws JSONException, SQLException {
// Get the current session object, create one if new
HttpSession session = request.getSession(true);
boolean validID = request.isRequestedSessionIdValid();
System.out.println("sessionID is valid : " + validID);
Date daysAgo = new Date(System.currentTimeMillis() - 10 * 1000);
Date created = new Date(session.getCreationTime());
long sessionAge = (System.currentTimeMillis() - created.getTime());
System.out.println("sessionAge : " + sessionAge);
// In case of relogin without logout
if (!session.isNew() && lastID != null) {
System.out.println("sessionID is " + sessionAge + "ms OLD... received ID : " + lastID);
if (lastID.equals(lastID)) {
JSONObj.remove("LoggedIn");
JSONObj.put("LoggedIn", lastID); // already LoggedIn with this sessionID
} else {
JSONObj.remove("LoggedIn");
JSONObj.put("LoggedIn", "Invalid"); // corrupted sessionID
}
}
// Invalidating a session if it's older than 24h
if (!session.isNew()) { // skip new sessions
if (created.before(daysAgo)) {
session.invalidate();
System.out.println("sessionID EXPIRED... invalidating ID : " + lastID);
languageConns.remove(lastID);
connections.remove(lastID);
lastID = null;
JSONObj.put("LoggedIn", "Expired"); //if sessionID expired
}
} else if (session.isNew()) {
session = request.getSession(false); //get a new session
lastID = session.getId();
System.out.println("sessionID is NEW or INVALID... generated ID : " + lastID);
JSONObj.remove("LoggedIn");
JSONObj.put("LoggedIn", lastID); // return a secure sessionID
connections.remove(lastID);
connections.put(lastID, conn);
languageConns.remove(lastID);
languageConns.put(lastID, lang);
System.out.println("languageConns : " + languageConns);
System.out.println("connections : " + connections);
}
session.setMaxInactiveInterval(86400);
System.out.println("JSONObj after validatingID : " + JSONObj);
return JSONObj;
}
问题:
在这段代码中,什么会导致 sessionID 仅在请求来自 android 客户端时被识别为新的,但在浏览器中运行时,相同的请求会按预期执行?
我希望这足够清楚。