Asp.net 自定义CustomerSession 存放到Redis中
首先,引用 Redis 操作驱动组件:StackExchange.Redis.dll。
继承SessionStateStoreProviderBase 类, 实现方法:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.SessionState; namespace KingSessionStateProvider
{
/// <summary>
/// 自定义Session类
/// </summary>
public class KingSessionStateProvider : SessionStateStoreProviderBase
{
/// <summary>
/// 获取配置文件的设置的默认超时时间
/// </summary>
private static TimeSpan _expiresTime; /// <summary>
/// 获取Web.config 在sessionState设置的超时时间
/// </summary>
static KingSessionStateProvider()
{
System.Web.Configuration.SessionStateSection sessionStateSection = (System.Web.Configuration.SessionStateSection)System.Configuration.ConfigurationManager.GetSection("system.web/sessionState");
_expiresTime = sessionStateSection.Timeout;
} /// <summary>
/// 创建要用于当前请求的新 SessionStateStoreData 对象。
/// </summary>
/// <param name="context"></param>
/// <param name="timeout"></param>
/// <returns></returns>
public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
{
return new SessionStateStoreData(new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), timeout);
} /// <summary>
/// 将新的会话状态项添加到数据存储区中。
/// </summary>
/// <param name="context"></param>
/// <param name="id"></param>
/// <param name="timeout"></param>
public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
{
/*
TODO: 保存数据库中
*/
var session = new ASPStateTempSessions
{
Created = DateTime.Now,
Expires = DateTime.Now.AddMinutes(timeout),
Flags = (int)SessionStateActions.InitializeItem,
LockDate = DateTime.Now,
Locked = false,
SessionId = id,
LockId = ,
Timeout = timeout
};
RedisDbHelper.Set(id, session);
} /// <summary>
/// 从会话数据存储区中返回只读会话状态数据。
/// </summary>
/// <param name="context"></param>
/// <param name="id"></param>
/// <param name="locked"></param>
/// <param name="lockAge"></param>
/// <param name="lockId"></param>
/// <param name="actions"></param>
/// <returns></returns>
public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{
return DoGet(false, context, id, out locked, out lockAge, out lockId, out actions); } /// <summary>
/// 从会话数据存储区中返回只读会话状态数据。
/// </summary>
/// <param name="context"></param>
/// <param name="id"></param>
/// <param name="locked"></param>
/// <param name="lockAge"></param>
/// <param name="lockId"></param>
/// <param name="actions"></param>
/// <returns></returns>
public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{
return DoGet(true, context, id, out locked, out lockAge, out lockId, out actions);
} /// <summary>
/// 获取Session的值
/// </summary>
/// <param name="isExclusive"></param>
/// <param name="context"></param>
/// <param name="id"></param>
/// <param name="locked"></param>
/// <param name="lockAge"></param>
/// <param name="lockId"></param>
/// <param name="actions"></param>
/// <returns></returns>
public SessionStateStoreData DoGet(bool isExclusive, HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
{ // 设置初始值
var item = default(SessionStateStoreData);
lockAge = TimeSpan.Zero;
lockId = null;
locked = false;
actions = ; // 如果数据存储区中未找到任何会话项数据,则GetItemExclusive 方法将 locked 输出参数设置为false,并返回 null。
// 这将导致 SessionStateModule调用 CreateNewStoreData 方法来为请求创建一个新的SessionStateStoreData 对象。
var session = RedisDbHelper.Get<ASPStateTempSessions>(id);
if (session == null)
{
return null;
} // 判断session是否是ReadOnly 模式,不是readonly模式得判断是否锁住
if (isExclusive)
{
// 如果在数据存储区中找到会话项数据但该数据已锁定,则GetItemExclusive 方法将 locked 输出参数设置为true,
// 将 lockAge 输出参数设置为当前日期和时间与该项锁定日期和时间的差,将 lockId 输出参数设置为从数据存储区中检索的锁定标识符,并返回 nul
if (session.Locked)
{
locked = true;
lockAge = session.LockDate - DateTime.Now;
lockId = session.LockId;
return null;
}
} // 判断是否过期
if (session.Expires < DateTime.Now)
{
RedisDbHelper.Remove(id); //移除条目
return null;
} // 处理值
lockId = lockId == null ? : (int)lockId + ;
session.Flags = (int)SessionStateActions.None;
session.LockId = Convert.ToInt32(lockId); // 获取timeout
var timeout = actions == SessionStateActions.InitializeItem ? _expiresTime.TotalMinutes : session.Timeout; // 获取SessionStateItemCollection
SessionStateItemCollection sessionStateItemCollection = null; // 获取Session的值
if (actions == SessionStateActions.None && (session.SessionItem != null))
{
sessionStateItemCollection = Deserialize(session.SessionItem);
} item = new SessionStateStoreData(sessionStateItemCollection ?? new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), (int)timeout); return item;
} /// <summary>
/// 释放对会话数据存储区中项的锁定。
/// </summary>
/// <param name="context"></param>
/// <param name="id"></param>
/// <param name="lockId"></param>
public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
{
var session = RedisDbHelper.Get<ASPStateTempSessions>(id);
if (session == null)
{
return;
}
// 把locked设置为false
session.Locked = false;
session.Expires = DateTime.Now + _expiresTime;
var bol = RedisDbHelper.Set(id, session);
} /// <summary>
/// 删除会话数据存储区中的项数据。
/// </summary>
/// <param name="context"></param>
/// <param name="id"></param>
/// <param name="lockId"></param>
/// <param name="item"></param>
public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
{
//Delete
if (RedisDbHelper.Exists(id))
{
RedisDbHelper.Remove(id);
}
} /// <summary>
/// 设置超时时间
/// </summary>
/// <param name="context"></param>
/// <param name="id"></param>
public override void ResetItemTimeout(HttpContext context, string id)
{
var session = RedisDbHelper.Get<ASPStateTempSessions>(id); if (session == null)
{
return;
}
session.Expires = DateTime.Now + _expiresTime;
var bol = RedisDbHelper.Set(id, session);
} /// <summary>
/// 使用当前请求中的值更新会话状态数据存储区中的会话项信息,并清除对数据的锁定。
/// </summary>
/// <param name="context"></param>
/// <param name="id"></param>
/// <param name="item"></param>
/// <param name="lockId"></param>
/// <param name="newItem"></param>
public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
{
// 判断是否是新建,如果是新建则和CreateUninitializedItem不同在于Timeout和有初始值。
if (newItem)
{
// 1. Clear an existing expired session if it exists.
if (RedisDbHelper.Exists(id))
{
RedisDbHelper.Remove(id);
} // 2. 保存到数据库中 注意须设置过期时间
// Expires = DateTime.Now.AddMinutes(item.Timeout) 设置过期时间
var session = new ASPStateTempSessions
{
Created = DateTime.Now,
Expires = DateTime.Now.AddMinutes(item.Timeout),
Flags = (int)SessionStateActions.None,
LockDate = DateTime.Now,
Locked = false,
SessionId = id,
LockId = ,
Timeout = item.Timeout,
SessionItem = Serialize((SessionStateItemCollection)item.Items)
//SessionItem = (SessionStateItemCollection)item.Items
};
var bol = RedisDbHelper.Set(id, session);
}
else// 释放锁定的项并设置Session的值
{
/*
if Find Session By Session return null
then retrun null
else set session value
Eg:
session.Expires = DateTime.Now.AddMinutes(item.Timeout);
session.Locked = false;
session.SessionItem = Serialize((SessionStateItemCollection)item.Items); */ var session = RedisDbHelper.Get<ASPStateTempSessions>(id);
if (session == null)
{
return;
} session.Expires = DateTime.Now.AddMinutes(item.Timeout);
session.Locked = false;
session.LockId = Convert.ToInt32(lockId);
session.SessionItem = Serialize((SessionStateItemCollection)item.Items);
//session.SessionItem = (SessionStateItemCollection)item.Items;
var bol = RedisDbHelper.Set(id, session);
}
} #region 序列化反序列化Session的值
/// <summary>
/// 反序列化Session的数据
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public SessionStateItemCollection Deserialize(string item)
{
byte[] bts = HexToByte(item);
MemoryStream stream = new MemoryStream(bts);
//MemoryStream stream = new MemoryStream(System.Text.Encoding.Unicode.GetBytes(item));
SessionStateItemCollection collection = new SessionStateItemCollection();
if (stream.Length > )
{
BinaryReader reader = new BinaryReader(stream);
collection = SessionStateItemCollection.Deserialize(reader);
}
return collection;
} /// <summary>
/// 将byte数组转换为16进制字符串
/// </summary>
/// <param name="bytes">要转换的数组</param>
/// <param name="iStart">数组下标</param>
/// <param name="iLength">长度</param>
/// <returns></returns>
public static string ToHexString(byte[] bytes) // 0xae00cf => "AE00CF "
{
string hexString = string.Empty;
if (bytes != null)
{
StringBuilder strB = new StringBuilder();
for (int i = ; i < bytes.Length; i++)
{
strB.Append(bytes[i].ToString("X2"));
}
hexString = strB.ToString();
}
return hexString;
}
/// <summary>
///
/// </summary>
/// <param name="hexString"></param>
/// <param name="discarded"></param>
/// <returns></returns>
public static byte[] GetBytes(string hexString, out int discarded)
{
discarded = ;
string newString = "";
char c;
// remove all none A-F, 0-9, characters
for (int i = ; i < hexString.Length; i++)
{
c = hexString[i];
if (Uri.IsHexDigit(c))
newString += c;
else
discarded++;
}
// if odd number of characters, discard last character
if (newString.Length % != )
{
discarded++;
newString = newString.Substring(, newString.Length - );
} return HexToByte(newString);
} /// <summary>
///
/// </summary>
/// <param name="hexString"></param>
/// <returns></returns>
public static byte[] HexToByte(string hexString)
{
if (string.IsNullOrEmpty(hexString))
{
hexString = "";
}
byte[] returnBytes = new byte[hexString.Length / ];
for (int i = ; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * , ), );
return returnBytes;
} /// <summary>
/// 序列化Session的数据
/// </summary>
/// <param name="items"></param>
/// <returns></returns>
public string Serialize(SessionStateItemCollection items)
{
MemoryStream ms = new MemoryStream();
BinaryWriter writer = new BinaryWriter(ms);
if (items != null)
items.Serialize(writer);
writer.Close(); //return System.Text.Encoding.Unicode.GetString(ms.ToArray());
//return Convert.ToBase64String(ms.ToArray());
return ToHexString(ms.ToArray());
} #endregion public override void Dispose()
{ } /// <summary>
/// 设置对 Global.asax 文件中定义的 Session_OnEnd 事件的 SessionStateItemExpireCallback 委托的引用
/// </summary>
/// <param name="expireCallback"></param>
/// <returns></returns>
public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback)
{
return true;
} /// <summary>
/// 由 SessionStateModule 对象调用,以便进行每次请求初始化。
/// </summary>
/// <param name="context"></param>
public override void InitializeRequest(HttpContext context)
{ }
public override void EndRequest(HttpContext context)
{ }
}
}
using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Text;using System.Web;using System.Web.SessionState;
namespace KingSessionStateProvider{ /// <summary> /// 金康自定义Session类 /// </summary> public class KingSessionStateProvider : SessionStateStoreProviderBase { /// <summary> /// 获取配置文件的设置的默认超时时间 /// </summary> private static TimeSpan _expiresTime;
/// <summary> /// 获取Web.config 在sessionState设置的超时时间 /// </summary> static KingSessionStateProvider() { System.Web.Configuration.SessionStateSection sessionStateSection = (System.Web.Configuration.SessionStateSection)System.Configuration.ConfigurationManager.GetSection("system.web/sessionState"); _expiresTime = sessionStateSection.Timeout; }
/// <summary> /// 创建要用于当前请求的新 SessionStateStoreData 对象。 /// </summary> /// <param name="context"></param> /// <param name="timeout"></param> /// <returns></returns> public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout) { return new SessionStateStoreData(new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), timeout); }
/// <summary> /// 将新的会话状态项添加到数据存储区中。 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="timeout"></param> public override void CreateUninitializedItem(HttpContext context, string id, int timeout) { /* TODO: 保存数据库中 */ var session = new ASPStateTempSessions { Created = DateTime.Now, Expires = DateTime.Now.AddMinutes(timeout), Flags = (int)SessionStateActions.InitializeItem, LockDate = DateTime.Now, Locked = false, SessionId = id, LockId = 0, Timeout = timeout }; RedisDbHelper.Set(id, session); }
/// <summary> /// 从会话数据存储区中返回只读会话状态数据。 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="locked"></param> /// <param name="lockAge"></param> /// <param name="lockId"></param> /// <param name="actions"></param> /// <returns></returns> public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return DoGet(false, context, id, out locked, out lockAge, out lockId, out actions);
}
/// <summary> /// 从会话数据存储区中返回只读会话状态数据。 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="locked"></param> /// <param name="lockAge"></param> /// <param name="lockId"></param> /// <param name="actions"></param> /// <returns></returns> public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) { return DoGet(true, context, id, out locked, out lockAge, out lockId, out actions); }
/// <summary> /// 获取Session的值 /// </summary> /// <param name="isExclusive"></param> /// <param name="context"></param> /// <param name="id"></param> /// <param name="locked"></param> /// <param name="lockAge"></param> /// <param name="lockId"></param> /// <param name="actions"></param> /// <returns></returns> public SessionStateStoreData DoGet(bool isExclusive, HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions) {
// 设置初始值 var item = default(SessionStateStoreData); lockAge = TimeSpan.Zero; lockId = null; locked = false; actions = 0;
// 如果数据存储区中未找到任何会话项数据,则GetItemExclusive 方法将 locked 输出参数设置为false,并返回 null。 // 这将导致 SessionStateModule调用 CreateNewStoreData 方法来为请求创建一个新的SessionStateStoreData 对象。 var session = RedisDbHelper.Get<ASPStateTempSessions>(id); if (session == null) { return null; }
// 判断session是否是ReadOnly 模式,不是readonly模式得判断是否锁住 if (isExclusive) { // 如果在数据存储区中找到会话项数据但该数据已锁定,则GetItemExclusive 方法将 locked 输出参数设置为true, // 将 lockAge 输出参数设置为当前日期和时间与该项锁定日期和时间的差,将 lockId 输出参数设置为从数据存储区中检索的锁定标识符,并返回 nul if (session.Locked) { locked = true; lockAge = session.LockDate - DateTime.Now; lockId = session.LockId; return null; } }
// 判断是否过期 if (session.Expires < DateTime.Now) { RedisDbHelper.Remove(id); //移除条目 return null; }
// 处理值 lockId = lockId == null ? 0 : (int)lockId + 1; session.Flags = (int)SessionStateActions.None; session.LockId = Convert.ToInt32(lockId);
// 获取timeout var timeout = actions == SessionStateActions.InitializeItem ? _expiresTime.TotalMinutes : session.Timeout;
// 获取SessionStateItemCollection SessionStateItemCollection sessionStateItemCollection = null;
// 获取Session的值 if (actions == SessionStateActions.None && (session.SessionItem != null)) { sessionStateItemCollection = Deserialize(session.SessionItem); }
item = new SessionStateStoreData(sessionStateItemCollection ?? new SessionStateItemCollection(), SessionStateUtility.GetSessionStaticObjects(context), (int)timeout);
return item; }
/// <summary> /// 释放对会话数据存储区中项的锁定。 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="lockId"></param> public override void ReleaseItemExclusive(HttpContext context, string id, object lockId) { var session = RedisDbHelper.Get<ASPStateTempSessions>(id); if (session == null) { return; } // 把locked设置为false session.Locked = false; session.Expires = DateTime.Now + _expiresTime; var bol = RedisDbHelper.Set(id, session); }
/// <summary> /// 删除会话数据存储区中的项数据。 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="lockId"></param> /// <param name="item"></param> public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item) { //Delete if (RedisDbHelper.Exists(id)) { RedisDbHelper.Remove(id); } }
/// <summary> /// 设置超时时间 /// </summary> /// <param name="context"></param> /// <param name="id"></param> public override void ResetItemTimeout(HttpContext context, string id) { var session = RedisDbHelper.Get<ASPStateTempSessions>(id);
if (session == null) { return; } session.Expires = DateTime.Now + _expiresTime; var bol = RedisDbHelper.Set(id, session); }
/// <summary> /// 使用当前请求中的值更新会话状态数据存储区中的会话项信息,并清除对数据的锁定。 /// </summary> /// <param name="context"></param> /// <param name="id"></param> /// <param name="item"></param> /// <param name="lockId"></param> /// <param name="newItem"></param> public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { // 判断是否是新建,如果是新建则和CreateUninitializedItem不同在于Timeout和有初始值。 if (newItem) { // 1. Clear an existing expired session if it exists. if (RedisDbHelper.Exists(id)) { RedisDbHelper.Remove(id); }
// 2. 保存到数据库中 注意须设置过期时间 // Expires = DateTime.Now.AddMinutes(item.Timeout) 设置过期时间 var session = new ASPStateTempSessions { Created = DateTime.Now, Expires = DateTime.Now.AddMinutes(item.Timeout), Flags = (int)SessionStateActions.None, LockDate = DateTime.Now, Locked = false, SessionId = id, LockId = 0, Timeout = item.Timeout, SessionItem = Serialize((SessionStateItemCollection)item.Items) //SessionItem = (SessionStateItemCollection)item.Items }; var bol = RedisDbHelper.Set(id, session); } else// 释放锁定的项并设置Session的值 { /* if Find Session By Session return null then retrun null else set session value Eg: session.Expires = DateTime.Now.AddMinutes(item.Timeout); session.Locked = false; session.SessionItem = Serialize((SessionStateItemCollection)item.Items);
*/
var session = RedisDbHelper.Get<ASPStateTempSessions>(id); if (session == null) { return; }
session.Expires = DateTime.Now.AddMinutes(item.Timeout); session.Locked = false; session.LockId = Convert.ToInt32(lockId); session.SessionItem = Serialize((SessionStateItemCollection)item.Items); //session.SessionItem = (SessionStateItemCollection)item.Items; var bol = RedisDbHelper.Set(id, session); } }
#region 序列化反序列化Session的值 /// <summary> /// 反序列化Session的数据 /// </summary> /// <param name="item"></param> /// <returns></returns> public SessionStateItemCollection Deserialize(string item) { byte[] bts = HexToByte(item); MemoryStream stream = new MemoryStream(bts); //MemoryStream stream = new MemoryStream(System.Text.Encoding.Unicode.GetBytes(item)); SessionStateItemCollection collection = new SessionStateItemCollection(); if (stream.Length > 0) { BinaryReader reader = new BinaryReader(stream); collection = SessionStateItemCollection.Deserialize(reader); } return collection; }
/// <summary> /// 将byte数组转换为16进制字符串 /// </summary> /// <param name="bytes">要转换的数组</param> /// <param name="iStart">数组下标</param> /// <param name="iLength">长度</param> /// <returns></returns> public static string ToHexString(byte[] bytes) // 0xae00cf => "AE00CF " { string hexString = string.Empty; if (bytes != null) { StringBuilder strB = new StringBuilder(); for (int i = 0; i < bytes.Length; i++) { strB.Append(bytes[i].ToString("X2")); } hexString = strB.ToString(); } return hexString; } /// <summary> /// /// </summary> /// <param name="hexString"></param> /// <param name="discarded"></param> /// <returns></returns> public static byte[] GetBytes(string hexString, out int discarded) { discarded = 0; string newString = ""; char c; // remove all none A-F, 0-9, characters for (int i = 0; i < hexString.Length; i++) { c = hexString[i]; if (Uri.IsHexDigit(c)) newString += c; else discarded++; } // if odd number of characters, discard last character if (newString.Length % 2 != 0) { discarded++; newString = newString.Substring(0, newString.Length - 1); }
return HexToByte(newString); }
/// <summary> /// /// </summary> /// <param name="hexString"></param> /// <returns></returns> public static byte[] HexToByte(string hexString) { if (string.IsNullOrEmpty(hexString)) { hexString = "00"; } byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return returnBytes; }
/// <summary> /// 序列化Session的数据 /// </summary> /// <param name="items"></param> /// <returns></returns> public string Serialize(SessionStateItemCollection items) { MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); if (items != null) items.Serialize(writer); writer.Close();
//return System.Text.Encoding.Unicode.GetString(ms.ToArray()); //return Convert.ToBase64String(ms.ToArray()); return ToHexString(ms.ToArray()); }
#endregion
public override void Dispose() {
}
/// <summary> /// 设置对 Global.asax 文件中定义的 Session_OnEnd 事件的 SessionStateItemExpireCallback 委托的引用 /// </summary> /// <param name="expireCallback"></param> /// <returns></returns> public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback) { return true; }
/// <summary> /// 由 SessionStateModule 对象调用,以便进行每次请求初始化。 /// </summary> /// <param name="context"></param> public override void InitializeRequest(HttpContext context) {
} public override void EndRequest(HttpContext context) {
} }}
Asp.net 自定义CustomerSession 存放到Redis中的更多相关文章
- 【PHP】如何将SESSION数据存放到Redis中
在php中,SESSION的数据默认是存放到文件中,这样性能不仅不高,而且不利于扩展.在搭建集群后,默认存放到文件中就不适用了.所以,我们一般将SESSION自定义,让SESSION中的数据存放到 数 ...
- 获取项目中文件,存放到Debug中。
说起这个,还真是费了一般功夫. 说个最简单的方法: 第一步:把需要生成到Debug中的文件放到项目中(注意:当前文件夹目录是什么样的,存放到Debug中也是什么样) 第二部:设置文件属性中 复制到输出 ...
- 乐视云监控数据存放到influxdb中
3.9 监控.告警系统 监控报警我们分PaaS平台和业务应用两大类. PaaS平台主要聚焦在基础设施和LeEngine的各个服务组件的监控报警(比如主机CPU,内存,IO,磁盘空间,LeEng ...
- Shiro Session放到Redis中常遇到的问题
Shiro会话管理:https://shiro.apache.org/session-management.html#SessionManagement-CustomSessionIDs Redis主 ...
- python爬虫——建立IP池,将可用IP存放到redis
直接上代码,每行代码后面都有注释 import urllib.request import urllib import re import time import random import sock ...
- byte数组怎么存放到Json中传递
可以把byte[]序列化成base64字符串后,再放json里传输就可以了.不需要考虑每个字节转成一个字符存到json字符串里. String str = Base64.encodeToString( ...
- Java微信公众号开发----定时获取access_token并保存到redis中
本人原本是想做微信公众号菜单的创建修改删除等操作的,但是发现需要access_token,通过阅读文档,发现文档要求有以下几点: 1.access_token 获取后有效期是2小时 2.access_ ...
- 根据从redis缓存的数据查询出来,在从数据库中取出所有的数据,俩个数据进行比较,去掉重复,剩下库中新插入的数据,取出新数据,然后把redis中的缓存数据清空把从数据库中查出来的所有数据放到redis缓存中
参考代码: public String getNewCenter(HttpServletRequest request,HttpServletResponse resonse){ JSONObject ...
- ssm+redis 如何更简洁的利用自定义注解+AOP实现redis缓存
基于 ssm + maven + redis 使用自定义注解 利用aop基于AspectJ方式 实现redis缓存 如何能更简洁的利用aop实现redis缓存,话不多说,上demo 需求: 数据查询时 ...
随机推荐
- Web开发——前后台异步调用
做web开发,最头疼的.最核心的部分或许就应该是前后台交互了,之前一直没弄明白,每次都不知道该如何去做.最近由于开发需要,加上有些朋友问起这个问题,不得不再次摸索前后台交互的方法.功夫不负有心人,总算 ...
- 3D开源推荐:3DWebExplorer
开源网址:https://github.com/irconde/3DWebExplorer 介绍:演示如何内嵌Google Earth 插件,开发面向公众的3D旅游展示平台
- App Inventor 网络资源及推荐书目
Ai2服务器 官方服务器:http://ai2.appinventor.edu/ 官方备用服务器:(大陆可用):http://contest.appinventor.mit.edu/ 国内个人服务器: ...
- sqlserver 带输出参数的存储过程
--创建存储过程create procedure proc_stu@sname varchar(20),@pwd varchar(50),@flag bit outputasif exists(sel ...
- 【java开发系列】—— 嵌套类与内部类
嵌套类与内部类在java中使用的很广泛,为了避免难以理解,这里用了几个小例子,说明它的用法. 嵌套类与内部类的结构如下图 静态嵌套类 静态嵌套类,是一种在类之外声明的嵌套类,由于是静态的,所以不经过初 ...
- ZT 父子进程共享文件描述符
转贴自倒霉熊的博客 [linux学习笔记-2]父子进程共享文件描述符 (2009-03-02 23:03:17) 转载▼ 标签: 学习 linux 子进程 文件描述符 杂谈 分类: 学习 #inclu ...
- 每天一个linux命令:df 命令
linux中df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况.可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息. 1.命令格式: df [选项] [文件] 2.命 ...
- 【LOJ2461】「2018 集训队互测 Day 1」完美的队列(分块+双指针)
点此看题面 大致题意: 让你维护\(n\)个有限定长度的队列,每次区间往队列里加数,求每次加完后的队列里剩余元素种类数. 核心思路 这道题可以用分块+双指针去搞. 考虑求出每个操作插入的元素在队列中被 ...
- PIL 图像字符画绘制
from PIL import Image ascii_char = list('"$%_&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]? ...
- 【[TJOI2017]城市】
题目 好像\(noip\)之前做某雅礼的题的时候看到过这道题的数据范围增强版 当时那道题数据范围是\(3e5\)感觉神仙的一批 这道题数据范围\(5e3\)那岂不是可以\(O(n^2)\)水过 有一点 ...