单机模式示例
//读取数据库中的数据
ServerResponse<User> response=iUserService.login(username,passward);
if (response.isSuccess()){
session.setAttribute(Const.CURRENT_USER,response.getData());
}
return response;
//判断是否登录
User user = (User)session.getAttribute(Const.CURRENT_USER);
单点登录实现思路:
1,读取数据库中的用户信息
2,获取session中的sessionId(我们称他为token)
3,将token放入cookie中(注意cookie存放的位置)
4,token作为键,序列化的用户信息作为值,存储到redis中
5,判断是否登录只要先从cookie中获取token,然后从redis中根据token查询用户信息
6,在拦截器中重置redis中的超时时间
那么我们开始吧
1,首先要写redis工具类,cookie工具类,slf4j工具类,序列化工具类。
Cookie
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieUtil {
private final static String Coodoman="localhost" ;
private final static String Cooname="login_name" ;
public static void writetoken(HttpServletResponse response,String token){
Cookie ck=new Cookie(Cooname,token);
ck.setDomain(Coodoman);
ck.setPath("/");
ck.setHttpOnly(true);
ck.setMaxAge(60*60*24*365);
pr.pr(ck.getName()+":"+ck.getValue());
response.addCookie(ck);
}
public static String readoken(HttpServletRequest request){
Cookie[] cks=request.getCookies();
if(cks!=null){
for (Cookie ck:
cks ) {
pr.pr(ck.getName()+"read:"+ck.getValue());
if(StringUtils.equals(ck.getName(),Cooname)){
pr.pr("readsuccess");
return ck.getValue();
}
}
}
return null;
}
public static void del(HttpServletRequest request,HttpServletResponse response){
Cookie[] cks=request.getCookies();
if(cks!=null){
for (Cookie ck:
cks ) {
pr.pr(ck.getName()+"read:"+ck.getValue());
if(StringUtils.equals(ck.getName(),Cooname)){
ck.setDomain(Coodoman);
ck.setPath("/");
ck.setMaxAge(0);
pr.pr("delsuccess");
response.addCookie(ck);
return;
}
}
}
}
}
Redis
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.6.0</version>
</dependency>
为了更加灵活,redis的一些配置我们放到resource目录下的xxx.properties
redis.max.total=20;
redis.max.idel=10;
redis.min.idel=2;
redis.test.borrow=true;
redis.test.return=true;
其次建立实体类然后把
public class RedisPool {
private static JedisPool pool; //jedis连接池
private static Integer maxTotal;//最大连接数
private static Integer maxIdle;//最大空闲状态
private static Integer minIdle;
private static Boolean textonBorrow; //Borrow是否验证
private static Boolean textonReturn; //Return是否验证
}
Common类
public class RedisPool {
private static JedisPool pool; //jedis连接池
private static Integer maxTotal= Integer.parseInt(PropertiesUtil.getProperty("redis.max.total","20"));//最大连接数
private static Integer maxIdle=Integer.parseInt(PropertiesUtil.getProperty("redis.max.idel","10"));//最大空闲状态
private static Integer minIdle=Integer.parseInt(PropertiesUtil.getProperty("redis.min.idel","2"));
private static Boolean textonBorrow=Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.borrow","true")); //Borrow是否验证
private static Boolean textonReturn=Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.return","true")); //Return是否验证
public static void initpool(){
JedisPoolConfig config=new JedisPoolConfig();
config.setMaxTotal(maxTotal);
config.setMaxIdle(maxIdle);
config.setMinIdle(minIdle);
config.setTestOnBorrow(textonBorrow);
config.setTestOnReturn(textonReturn);
pool=new JedisPool(config,"106.14.13.61",6379,1000*2);
}
static {
System.out.println("static");
initpool();
}
public static Jedis getjedis(){
return pool.getResource();
}
public static void returnbrokenresource(Jedis jedis){
pool.returnBrokenResource(jedis);
}
public static void returnresource(Jedis jedis){
pool.returnResource(jedis);
}
public static void main(String [] args){
// Jedis jedis=pool.getResource();
// jedis.set("kk","vv");
// returnresource(jedis);
// pool.destroy();
// System.out.println("6");
System.out.println(RedispoolUtil.setex("kk",1000,"ss"));
}
}
JedisUtil类
package com.mmall.util;
import com.mmall.common.RedisPool;
import redis.clients.jedis.Jedis;
public class RedispoolUtil {
/*
* key有效期
* */
public static Long expire(String key,int extime){
Jedis jedis=null;
Long result=null;
try{
jedis= RedisPool.getjedis();
result=jedis.expire(key,extime);
}catch (Exception e){
System.out.println("weong");
RedisPool.returnbrokenresource(jedis);
return result;
}
RedisPool.returnresource(jedis);
return result;
}
/*
增加数据
* */
public static String setex(String key,int extime,String value){
Jedis jedis=null;
String result=null;
try{
jedis= RedisPool.getjedis();
result=jedis.setex(key,extime,value);
}catch (Exception e){
System.out.println("weong");
RedisPool.returnbrokenresource(jedis);
return result;
}
RedisPool.returnresource(jedis);
return result;
}
/*
得到数据
* */
public static String get(String key){
Jedis jedis=null;
String result=null;
try{
jedis= RedisPool.getjedis();
result=jedis.get(key);
}catch (Exception e){
System.out.println("weong");
RedisPool.returnbrokenresource(jedis);
return result;
}
RedisPool.returnresource(jedis);
return result;
}
/*
删除数据
* */
public static Long del(String key){
Jedis jedis=null;
Long result=null;
try{
jedis= RedisPool.getjedis();
result=jedis.del(key);
}catch (Exception e){
System.out.println("weong");
RedisPool.returnbrokenresource(jedis);
return result;
}
RedisPool.returnresource(jedis);
return result;
}
}
slf4j读取配置文件
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
/**
* 加载配置
*/
public class PropertiesUtil {
private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);
private static Properties props;
static {
String fileName = "mmall.properties";
props = new Properties();
try {
props.load(new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName),"UTF-8"));
} catch (IOException e) {
logger.error("配置文件读取异常",e);
}
}
public static String getProperty(String key){
String value = props.getProperty(key.trim());
if(StringUtils.isBlank(value)){
return null;
}
return value.trim();
}
public static String getProperty(String key,String defaultValue){
String value = props.getProperty(key.trim());
if(StringUtils.isBlank(value)){
value = defaultValue;
}
return value.trim();
}
}
序列化(对象to json以便存在value中)
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.12</version>
</dependency>
序列化utils
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.type.TypeReference;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.logging.Logger;
public class JsonUtil {
private static ObjectMapper objectMapper=new ObjectMapper();
static {
//对象所有字段转入
objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.ALWAYS);
//取消timestamps
objectMapper.configure(SerializationConfig.Feature.WRITE_DATE_KEYS_AS_TIMESTAMPS,false);
//忽略空bean
objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS,false);
objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.STANDARD_FORMAT));
//忽略在json中存在,但是java对象不存在
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,false);
}
public static <T> String objstring(T obj){
if(obj==null){
return null;
}
try {
return obj instanceof String? (String) obj:objectMapper.writeValueAsString(obj);
}catch (Exception e){
return null;
}
}
public static <T> String objstringorety(T obj){
if(obj==null){
return null;
}
try {
return obj instanceof String? (String) obj:objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
}catch (Exception e){
return null;
}
}
public static <T> T strtoobj(String str,Class<T> clazz){
if(StringUtils.isEmpty(str)){
return null;
}
try {
return clazz.equals(String.class)? (T) str :objectMapper.readValue(str,clazz);
} catch (Exception e) {
return null;
}
}
public static <T> T strtoobj(String str, TypeReference<T> typeReference){
if(StringUtils.isEmpty(str)||typeReference==null){
return null;
}
try {
return typeReference.getType().equals(String.class)? (T) str : (T) objectMapper.readValue(str, typeReference);
} catch (Exception e) {
return null;
}
}
public static void main(String [] args){
User u1=new User();
u1.setId(1);
u1.setUsername("wpp");
User u2=new User();
u2.setId(1);
u2.setUsername("wpp");
List<User> ul= Lists.newArrayList();
ul.add(u1);
ul.add(u1);
System.out.println(JsonUtil.strtoobj(JsonUtil.objstring(ul), new TypeReference<List<User>>() {
}));
}
}
2,实现登录
ServerResponse<User> response=iUserService.login(username,passward);
if (response.isSuccess()){
CookieUtil.writetoken(resp,session.getId());
RedispoolUtil.setex(session.getId(), 1800,JsonUtil.objstring(response.getData()));
}
3,实现验证
@RequestMapping(value = "us.do",method = RequestMethod.GET)
@ResponseBody
public ServerResponse<User> de(String username, String passward , HttpSession session, HttpServletResponse resp, HttpServletRequest request){
String to=CookieUtil.readoken(request);
if(StringUtils.isEmpty(to)){
return ServerResponse.createByErrorCodeMessage(8,"nosession");
}
String json=RedispoolUtil.get(to);
User us=JsonUtil.strtoobj(json,User.class);
if(us!=null){
pr.pr(us.getUsername()+us.getPhone());
return ServerResponse.createBySuccess(us);
}
return ServerResponse.createByErrorCodeMessage(8,"noredis");
}
4,Session重置有效期
public class FILTER implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest=(HttpServletRequest)servletRequest;
String tok=CookieUtil.readoken(httpServletRequest);
if(StringUtils.isNotEmpty(tok)){
String jsons= RedispoolUtil.get(tok);
User user=JsonUtil.strtoobj(jsons,User.class);
if(user!=null){
RedispoolUtil.expire(tok,60*30);
}
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
<filter>
<filter-name>filtersession</filter-name>
<filter-class>com.mmall.controller.COMMON.FILTER</filter-class>
</filter>
<filter-mapping>
<filter-name>filtersession</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>